目录
前言
4、文件的顺序读写
4.1fputc
4.2 fgetc
4.3 fputs
4.4 fgets
4.5 fprintf
4.6 fscanf
4.7 fread和fwrite
结(二)
前言
接者“C语言:文件操作(一)”往下讲。
本篇文章将介绍C语言的文件操作,在后面的内容讲到:为什么使用文件;什么是文件;文件的打开和关闭;文件的顺序读写;文件的随机读写;文本文件和二进制文件;文件读取和结束的判定;文件缓冲区。详细讲述了C语言的文件操作。此内容将分成三篇讲解,这是第二篇。
4、文件的顺序读写
顾名思义,按照顺序对文件进行读写,就是文件的顺序读写。下面会具体讲解。我们先来看看主要的函数:
功能 | 函数名 | 适用情况 |
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出 流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
4.1fputc
fputc的参数有两个,第一个参数是要输入的字符的ASCII码,第二个参数是要输入文件的文件指针。
下面举一个例子:
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "w");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//写文件
char i = 0;
for (i = 'a';i <= 'z';i++)
{
fputc(i, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
这样的代码运行,我们发现在程序的路径下会多出一个文件:
这个文件打开后发现内容正式我们在程序中对文件的输入。
这是因为本身我们程序路径下是没有文件“test.txt”的,所以当我们以写的形式(“w”)去打开文件时,电脑就会在当前路径下创建一个文件“test.txt”,然后我们在后面利用fputc函数将“a”到“z”的字符输入到了该文件,因此文件内的内容就是“a”到“z”。
fputc就讲到这,下面讲它相对的一个函数,fgetc。
4.2 fgetc
fgetc的参数只有个就是文件指针,这个函数功能就是按顺序输出文件的内容,当输出失败时返回EOF。利用这个特性我们可以写一个函数。
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//读文件
int ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
printf("%c ", ch);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
效果如下:
我们读取了刚刚用fputc创建的文件“test.txt”,然后再通过fgetc的特性:在没有输出时返回EOF。我们将循环的条件改为,当fgetc返回值为EOF时停止,这样就能访问文件的所有内容。于是就产生的上面这样的效果。
4.3 fputs
fputs的参数有两个,和foutc类似,只不过第一个参数是要输入的字符串的首地址而不是字符的ASCII码。第二个参数是要输入的文件的文件指针。
看代码:
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "w");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//写文件
fputs("hello world", pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
效果就是在当前路径下的文件“tese.txt”的内容改成hello world
没错,它会销毁文件之前的内容(之前本来内容是“a”到“z”),如果想在原来文件内容不变的情况下进行追加内容,那适用fopen函数时,应该以"a"的形式打开文件(追加形式)。
4.4 fgets
读一行fgets有两个参数,第一个参数是读取的内容要存放的空间(这个要提前给创建好),第二个参数是要读取得字符个数,第三个参数是要读取得文件的文件指针。
下面看例子:
int main()
{
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//读文件
char arr[20] = { 0 };
fgets(arr, 5, pf);
printf("%s", arr);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
效果:
发现只读了四个字符,这是因为需要有一个字符放'\0',所以,读n个字符,得到的其实n-1个字符加一个'\0'。
4.5 fprintf
我们发现不管用fputc还是fputs,都只能对字符进行一个写入,如果要对其他类型进行写入的话,我们就需要用到fprintf。
fprintf的参数类比printf,比printf在最前面多一个参数:FILE*类型的参数。其实就是在原来printf函数前补充一个文件指针,下面看个例子就明白了:
#include<stdio.h>
#include<string.h>
#include<errno.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { "zhangsan",25,50.5f };
FILE* pf = fopen("test.txt", "w");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//写文件
fprintf(pf , "%s %d %f", s.arr,s.age,s.score);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
这个例子,我先创建了一个结构体struct S,然后初始化了一个结构体变量s,后通过fprintf函数将其三个内容写入文件“test.txt”,我们发现fprintf其实就是比printf多加一个参数文件指针,就可以把内容打印到文件当中去,效果如下:
4.6 fscanf
同理,fscanf和scanf很像,就是在它前面加了一个文件指针的参数。
下面看一个例子:
#include<stdio.h>
#include<string.h>
#include<errno.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { 0 };
FILE* pf = fopen("test.txt", "r");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//读文件
fscanf(pf, "%s %d %f", s.arr, &(s.age), &(s.score));
printf("%s %d %f", s.arr, s.age, s.score);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
利用一下我们刚刚创建好的文件,看看效果:
我们这样就把文件的内容读出来了。
剩下的两个函数:fread和fwrite是二进制的读和写,将数据转化为二进制之后进行读写。且对象只能是文件。
4.7 fread和fwrite
先看fwrite:
这里有四个参数,首先知道第四个参数是文件指针,然后我们来看第一个参数,第一个参数是要写入的内容的地址,第二个参数是要写入的数据大小,第三个参数是要写入的数据个数。
下面看程序:
#include<stdio.h>
#include<string.h>
#include<errno.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { "zhangsan" , 25, 50.5f };
FILE* pf = fopen("test.txt", "wb");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//写文件
fwrite(&s, sizeof(struct S), 1, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
这里要注意:我们打开文件的方式应该是wb:以二进制的方式打开。
看效果:
我们发现有些东西我们看不懂,这是因为我们放进去的是二进制,所以我们无法看懂,但由于“zhgangsan”我们以文本和以二进制的方式放进去是一样的,所以显示出来我们看得懂。
虽然我们看不懂这个函数,但我们可以用fread把他读取出来,fread正好可以读取二进制的数据。
fread:
fread有四个参数,其实我们发现fread和fwrite的参数是一样的,只是作用相反。
看代码:
#include<stdio.h>
#include<string.h>
#include<errno.h>
struct S
{
char arr[10];
int age;
float score;
};
int main()
{
struct S s = { 0 };
FILE* pf = fopen("test.txt", "rb");
if (NULL == pf)
{
printf("%s\n", strerror(errno));
return 1;
}
//读文件
fread(&s, sizeof(struct S), 1, pf);
printf("%s %d %f", s.arr, s.age, s.score);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
效果:
虽然二进制方式放进去我们看不懂,但是我们可以用fread把他读出来。
二进制写进去文件可能会小一些,但也不一定,看情况,所以按什么方式放数据到文件里面,需要我们自己根据情况去判断。
结(二)
C语言:文件操作(二)的内容,就到此,后续会继续讲解后面的内容。希望本篇文章对你有所帮助。