目录
1.文件
1.1程序文件
1.2数据文件
2.文件名
3.文件的打开和关闭
3.1文件指针
3.2文件的打开和关闭
4.文件的顺序读写
4.1fgetc
4.2fputc
4.3fgets
4.4fputs
4.5fscanf
4.6fprintf
4.7fread(二进制输出)
4.8fwriite(二进制输入)
5.文件的随机读写
5.1fseek
5.2ftell
5.3rewind
6.文件读取结束的判断
包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
文件名包含3部分:文件路径+文件名主干+文件后缀
例如:c:\code\test.txt
文件指针,指的是文件类型指针,为指针的一种。当文件被使用的时候会在内存中开辟一个相应的文件信息区,用来存放文件相关信息。这些信息保存在一个结构体变量中,该结构体类型是有系统声明的,取名为FILE。
创建一个文件指针变量:
FILE* pf;
以上定义了pf为指向FILE类型数据的指针变量,可以使pf指向某个文件的文件信息区。通过文件信息区的信息就能够访问文件,也就是通过文件指针变量能够找到与其相关联的文件。
在对文件进行操作前应先打开文件,在使用结束后应关闭相应的文件。
我们通过fopen和fclose函数来对文件进行打开与关闭:
文件的打开
FILE *fopen(const char *filename, const char *mode)//打开文件
filename是要打开的文件的文件名,mode为文件的打开方式。文件的打开方式如下
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
r | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
w | 为了输出数据,打开一个文本文件 | 建立一个新文件 |
a | 向文本文件尾添加数据 | 建立一个新文件 |
rb | 为了输入数据,打开一个二进制文件 | 出错 |
wb | 为了输出数据,打开一个二进制文件 | 建立一个新文件 |
ab | 向二进制文件尾添加数据 | 出错 |
r+ | 为了读和写,打开一个文本文件 | 出错 |
w+ | 为了读和写,建立一个新的文件 | 建立一个新文件 |
a+ | 打开一个文件,在文件尾进行读写 | 建立一个新文件 |
rb+ | 为了读和写打开一个二进制文件 | 出错 |
wb+ | 为了读和写,新建一个新的二进制文件 | 建立一个新文件 |
ab+ | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新文件 |
文件的关闭
int fclose(FILE *stream)
功能 | 函数名 | 适用于 |
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
int fgetc(FILE *stream);
fgetc函数从指定的流从获取下一个无符号字符,并把光标移动到下一位。此函数的返回值为int整型,返回相应字符的ASCII值。
会按照顺序获取字符,如果文件中的信息为‘abcd’,第一次fgetc为‘a’,第二次使用则为‘b’,以此类推。
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
perror("fopen");
}
int ch = fgetc(pf);
printf("%c\n", ch);
printf("%d", ch);
fclose(pf);
return 0;
}
int fputc(int char, FILE *stream) ;
fputc函数把指定的char参数写入到指定的流中,并把光标向前移动一位。
int main()
{
FILE* pf = fopen("test.txt", "w");
if (NULL == pf)
{
perror("fopen");
}
fputc('a', pf);
for (char i = 'b'; i <= 'e'; i++)
{
fputc(i, pf);
}
fclose(pf);
return 0;
}
值得注意的是,再下一次重新使用fputc的时候会将第一次已经输入好的数据进行覆盖。
fputc('a', pf);
for (char i = 'o'; i <= 'q'; i++)
{
fputc(i, pf);
}
再次查看文本,得到的是:
char *fgets(char *str, int n, FILE *stream)
当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
当你想要读取a个字符的时候,参数n应填上a+1。因为要给\0留上一个空位
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
perror("fopen");
}
char str[10] = { 0 };
fgets(str, 6, pf);
printf("%s", str);
fclose(pf);
return 0;
}
int fputs(const char *str, FILE *stream)
写入指定的字符串到指定的流中,并把位置标识符往前移。
int main()
{
FILE* pf = fopen("test.txt", "w");
if (NULL == pf)
{
perror("fopen");
}
fputs("happy chinese new year\n", pf);
fputs("恭喜发财", pf);
fclose(pf);
return 0;
}
int fscanf(FILE *stream, const char *format, ...)
从流 stream 读取格式化输入.
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
perror("fopen");
}
int a = 0;
char ch = 0;
char name[10] = {0};
fscanf(pf, "%d %c %s", &a, &ch, name);
printf("%d %c %s\n", a, ch, name);
fclose(pf);
return 0;
}
发送格式化输出到流 stream 中,和printf差不多,按照printf的格式写完后,在前面加上指定的文件指针即可。
int fprintf(FILE *stream, const char *format, ...)
int main()
{
FILE* pf = fopen("test.txt", "w");
if (NULL == pf)
{
perror("fopen");
}
int a = 1;
char ch = 'z';
char name[] = "zhangsan";
fprintf(pf, "%d %c %s", a, ch, name);
fclose(pf);
return 0;
}
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
从给定流 stream 读取数据到 ptr 所指向的数组中
int main()
{
FILE* pf = fopen("test.txt", "rb");
if (NULL == pf)
{
perror("fopen");
}
char str[20] = {0};
fread(str, sizeof(str), 1, pf);
printf("%s", str);
fclose(pf);
return 0;
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
以二进制的形式对文件进行操作,把 ptr 所指向的数组中的数据写入到给定流 stream 中
int main()
{
FILE* pf = fopen("test.txt", "wb");
if (NULL == pf)
{
perror("fopen");
}
char str[20] = "hello";
fwrite(str, sizeof(str), 1, pf);
fclose(pf);
return 0;
}
int fseek(FILE *stream, long int offset, int whence)
whence表示开始添加偏移 offset 的位置,有以下几种常量。
fseek函数起到的作用为,改变光标的位置,对下一步的操作进行处理。
SEEK_SET | 文件的开头 |
SEEK_CUR | 文件指针的当前位置 |
SEEK_END | 文件的末尾 |
此时文本当中的信息为:abcdef
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
perror("fopen");
}
char ch;
ch = fgetc(pf);
printf("%c", ch);
ch = fgetc(pf);
printf("%c", ch);
fseek(pf, 0, SEEK_SET);//从初始位置开始,不偏移
ch = fgetc(pf);
printf("%c", ch);
fseek(pf, -2, SEEK_END);//从末尾位置开始,向左偏移两位
ch = fgetc(pf);
printf("%c", ch);
fclose(pf);
return 0;
}
long int ftell(FILE *stream)
返回相对于起始位置的偏移量,就是目前光标所在的位置
文件中的信息为:abcdef
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
perror("fopen");
}
char ch;
ch = fgetc(pf);
printf("%c", ch);
ch = fgetc(pf);
printf("%c", ch);
fseek(pf, 0, SEEK_SET);//从初始位置开始,不偏移
ch = fgetc(pf);
printf("%c", ch);
fseek(pf, -2, SEEK_END);//从末尾位置开始,向左偏移两位
ch = fgetc(pf);
printf("%c", ch);
printf("%d", ftell(pf));//光标目前的位置
fclose(pf);
return 0;
}
最后获取的字符为e,位于向左偏移5位处。
void rewind(FILE *stream)
让光标回到文件的初始位置
rewind(pf);
pf为文件指针
1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
fgetc 判断是否为 EOF .
fgets 判断返回值是否为 NULL .
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
例如:
fread判断返回值是否小于实际要读的个数。