一、基础知识:
1.什么是IO:linux下读写文件的方式。
2.什么是流:标准IO的操作对象 。(是描述文件信息的结构体)
二、标准IO操作:
打开文件 — 读写 — 关闭文件
1. 打开操作:
#include <stdio.h>
FILE *fopen (const char *__restrict __filename,const char *__restrict __modes);
// 功能:打开或创建文件
// 参数1:同open
// 参数2:同open的flag文件打开的方式
// r: 以只读的方式打开,文件已存在
// r+: 以读写方式打开,文件已存在
// w:以只写方式打开 文件内容会清空 如果文件不存在 则创建 存在则打开
// w+:以读写方式打开 文件内容会清空 如果文件不存在 则创建 存在则打开
// a:以追加写的方式打开 如果文件不存在 则创建
// a+:以读写方式追加 如果文件不存在 则创建.写入的数据会被加到文件尾后,读取时从文件起始位置
// 返回值:成功返回FILE*类型文件流指针 失败NULL
练习: 输入文件名字,判断文件是否存在
int main(int argc, const char *argv[])
{
if (argc != 2)
{
printf("input argument unreasonable!\n");
return 0;
}
FILE *fp = fopen(argv[1], "r");
if (NULL == fp)
{
perror("fopen");
printf("file:[%s] is't exist.\n", argv[1]);
return 0;
}
else
{
printf("file:[%s] is exist.\n", argv[1]);
}
return 0;
}
2. 读一行
char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
/* 功能:从文件中读取一个行
* 参数1:读取数据存放的位置
* 参数2:最多读多大 size大小包含‘\0’所以实际读到的有效字符最多为size-1个有效字符
* 参数3:文件流指针、
* 返回值:成功返回读到的数据,失败或到文件结尾返回NULL
*/
例子: 读取整个文件,并统计文件行数
int main(int argc, const char *argv[])
{
if (argc != 2)
{
printf("input argument unreasonable!\n");
return 0;
}
FILE *fp = fopen(argv[1], "r");
if (NULL == fp)
{
perror("fopen");
return 0;
}
char buf[10] = "\0";
char *ptr = NULL;
int line = 0;
while (1)
{
bzero(buf, sizeof(buf));
ptr = fgets(buf, sizeof(buf), fp);
if (buf[8] == '\0' || buf[8] == '\n')
{
line++;
}
if (ptr == NULL)
{
perror("fgets");
break;
}
printf("%s", buf);
}
printf("\nlen: %d\n", line);
return 0;
}
3. 写一行
int fputs (const char *__restrict __s, FILE *__restrict __stream);
/**
* 功能:向文件中写一行
* 参数1:要写的内容
* 参数2:写到哪里
* 返回值:成功返回非负数,失败EOF(文件结束标志)
* 注意: #define EOF -1
*/
练习: 存在文件my.h(有内容)读取my.h中内容,并且将读取的内容写入b.txt
#include "my.h"
int main(int argc, const char *argv[])
{
if (argc != 3)
{
printf("input arfuement unreasonable!\n");
return 0;
}
FILE *fpR = fopen(argv[1], "r+"); // 打开文件
if (fpR == NULL) // 错误校验,下面同理
{
perror("fpR[fopen]");
return 0;
}
FILE *fpW = fopen(argv[2], "w+");
if (fpW == NULL)
{
perror("fpw[fopen]");
return 0;
}
char buf[100] = "\0"; // 清空
char *R_ret = NULL; // 避免野指针
int W_ret;
while (1) // copy
{
R_ret = fgets(buf, sizeof(buf), fpR); // 读1行
if (R_ret == NULL) // 读失败
{
perror("fgets");
return 0;
}
W_ret = fputs(R_ret, fpW); // 写内容
if (W_ret == EOF)
{
perror("fputs");
return 0;
}
}
fclose(fpR);
fclose(fpW);
return 0;
}
4. 关闭文件
int fclose (FILE *__stream);
// 功能:关闭文件fp
5. 按字节读写
-
写操作:
int fputc (int __c, FILE *__stream); // 功能: 向文件中写入一个字符 // 返回值:成功返回写入字符,错误返回EOF
-
读操作:
int fgetc (FILE *__stream); // 功能:从文件中读取一个字符 // 返回值:成功返回读取道德字符,到文件结尾返回EOF
练习: 存在文件a.txt(有内容) 读取a.txt中内容 并且将读取的内容写入b.txt cp
#include "my.h"
// 存在文件a.txt(有内容) 读取a.txt中内容 并且将读取的内容写入b.txt cp
// 采用fputc()和fgetc()实现
int main(int argc, const char *argv[])
{
// 采用命令行传参,argc == 3
if (argc != 3)
{
printf("input argument unreasonable!\n");
return 0;
}
// 1.打开文件
FILE *fpSrc = fopen(argv[1], "r"); // cpoy的源文件,以只读方式打开
if (fpSrc == NULL)
{
perror("Src open");
return 0;
}
FILE *fpDes = fopen(argv[2], "w"); // 打开目标文件
if (fpDes == NULL)
{
perror("Des open");
return 0;
}
char bufC = fgetc(fpSrc); // 读一个字符
int ret = 0;
while (bufC != EOF)
{
ret = fputc(bufC, fpDes); // 写入一个字符
if (ret == EOF)
{
perror("fputc");
return 0;
}
bufC = fgetc(fpSrc);
}
return 0;
}