文件读取
C语言中除了文件写入外,还提供了文件读取函数,下面分别对C语言中的文件读取函数进行讲解。
1、使用fgetc()函数读取文件中的字符
fgetc()函数用于读取文件中的字符,函数声明如下:
int fgetc(FILE* stream);
上述函数声明中,参数stream表示一个文件指针。函数将读取的字符转换成整数返回,读取文件到达末尾或读取错误时返回EOF。
接下来通过一个具体案例演示如何使用fgetc()函数读取文件中的字符,首先在当前项目路径下新建文件“hello.txt”,输入“I am a student ,I am 18 years old.”保存。如例1所示。
例1 fgetcFile.c
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <stdlib.h>
4 int main()
5 {
6 FILE *fp;
7 char ch;
8 fp = fopen("hello.txt", "r");
9 if (fp == NULL)
10 {
11 printf("打开文件失败!\n");
12 exit(0);
13 }
14 ch = fgetc(fp); // 从文件中读取每个字符
1 while (ch != EOF) // 只要文件没读到结尾,就执行下面的代码
2 {
3 printf("%c", ch);
4 ch = fgetc(fp);
5 }
6 printf("\n");
7 fclose(fp);
8 return 0;
9 }
例1运行结果如图1所示。
图1 例1运行结果
从图1中可以看出,文件hello.txt中的内容被读取成功了。
例1中,第8行代码定义了一个文件指针并以只读的方式打开文件;第15~19行代码在while循中调用fgetc()函数读取文件中的字符并输出至控制台;第21行代码调用fclose()函数关闭文件。
2、使用fgets()函数读取文件中的字符串
fgets()函数用于从文件中读取一行字符串,或读取指定长度的字符串,函数声明如下:
char * fgets(char * s, int size, FILE * stream);
上述函数声明中,参数s指向用来存储数据的空间;参数size表示读取数据的大小;参数stream表示要读取的文件的文件指针。函数读取成功返回s,如果读取错误或遇到文件末尾,返回NULL。
fgets()函数从文件指针stream指向的文件中读取数据,最多读取size-1个字符,将读取的数据保存到s指向的字符数组中,读取的字符串会在最后一位添加‘\0’。
fgets()函数停止读取的情况通常包括以下三个:
(1) 读取size-1个字符前,遇到‘\n’,读取结束,末尾添加‘\0’。
(2) 读取size-1个字符前,遇到EOF,读取结束,末尾添加‘\0’。
(3) 完成size-1个字符读取,读取结束后,末尾添加‘\0’。
接下来通过一个具体案例学习如何使用fgets()函数读取文件中的字符串,在工程根目录新建poem.txt,输入一段话后保存。调用fgets()函数读取poem.txt中的内容,如例2所示。
例2 fgetsFile.c
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 int main()
6 {
7 FILE * fp; // 声明文件指针
8 char str[256]; // 文件数据缓冲区
9 memset(str, 0, sizeof(str)); // 初始化文件数据缓冲区
10 fp = fopen("poem.txt", "r"); // 打开文件,并将文件和文件指针关联
11 if (fp == NULL) // 打开文件失败,打印出错信息
12 {
13 printf("打开文件失败!\n");
14 exit(0); // 退出程序
15 }
16 while (!feof(fp)) // 判断文件指针是否已指向文件的末尾
17 {
18 fgets(str, sizeof(str), fp);// 按行将文件中的字符串复制到文件数据缓冲区中
19 printf("%s", str); // 打印文件数据缓冲区中的字符串
20 }
21 fclose(fp); // 关闭文件,释放资源
22 return 0;
23 }
例2运行结果如图2所示。
图2 例2运行结果
在例2中,第10行代码定义一个字符数组并以只写的方式打开poem.txt文件;第16~20行代码在while循环中,调用fgets()函数读取文件中的每一行字符串到字符数组中,并打印出来;第21行代码调用fclose()函数关闭文件。从图2中可以看出,文件读取操作成功。
3、使用fread()以二进制形式读取文件
fread()函数用于以二进制形式读取文件,函数声明如下:
size_t fread(void * ptr, size_t size,size_t nmemb, FILE * stream);
上述函数声明中,参数ptr表示指向要接收读取数据的内存空间的指针;参数size表示读取元素的大小,以字节为单位;参数nmemb表示读取元素的个数;参数stream表示读取文件的文件指针。函数返回值类型为size_t类型,即返回值的类型为无符号整型。
fread()函数从一个文件中读取数据,最多读取nmemb个元素,每个元素大小为size个字节。读取成功则返回读取数据的大小。读取错误返回0。
接下来通过一个案例来练习如何使用fread()函数读取文件数据,首先在项目根目录新建“fread.txt”文件在文件中输入26个小写英文字母后保存,如例3所示。
例3 freadFile.c
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 int main()
6 {
7 FILE* fp; // 声明文件指针
8 char str[32]; // 声明数据数组
9 memset(str, 0, sizeof(str)); // 初始化数据数组
10 size_t len=0; //记录读取数据的长度
11 fp = fopen("fread.txt", "r"); // 以只读方式打开一个文件
12 if (fp == NULL) // 打开文件失败,打印出错信息
13 {
14 printf("文件打开失败\n");
15 exit(0); // 退出程序
16 }
17 while (!feof(fp)) // 判断文件指针是否已指向文件的末尾
18 {
19 len=fread(str, 1, 31, fp); // 将文件中的数据复制到数据数组中
20 printf("%s\n", str); // 打印数组中的数据
21 }
22 fclose(fp); // 关闭文件,释放资源
23 printf("读取的实际大小为:%d", len);
24 return 0;
25 }
第7行代码定义了数组str用于存储读取数据的空间,第8行代码将str数组空间的元素填充为0,第10行代码初始化变量len用于记录读取字符的个数。第17~21行代码在while()循环中fread()函数读取文件中的内容,直到读取到文件末尾时结束,第22行代码在读取结束后关闭文件。
例3运行结果如图3所示。
图3 例3运行结果
从图3中可以看出,文件中的数据被输出到控制台,使用fread()函数成功读取了文件中的内容。需要注意的是,二进制模式下,具有特殊意义的字符,如‘\n’和‘\0’,就没有意义了。
4、使用fscanf()函数格式化读取文件
fscanf()函数用于从文件中格式化读取数据,函数声明如下:
int fscanf(FILE * stream, const char * format, ...);
上述函数声明中,参数stream表示文件指针;参数format表示文件中的字符串以什么样的格式输入到程序中;返回值类型int表示函数返回值的类型为整型。
fscanf()函数格式化读取文件中的数据,如果函数调用成功,返回值是输入的参数的个数;否则,返回EOF。
接下来通过一个具体案例来演示如何使用fscanf()函数格式化读取文件,首先在项目根目录下新建文件hello.txt输入“hello world”后保存,文件内容如图4所示。
图4 hello.txt文件内容
使用fscanf()函数读取文件中的内容,如例4所示。
例4 fscanfFile.c
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 #include <stdlib.h>
4 int main()
5 {
6 char str1[10], str2[10];
7 FILE* fp;
8 fp = fopen("hello.txt", "r");
9 fscanf(fp, "%s %s", str1, str2);
10 fclose(fp);
11 printf("%s\n", str1);
12 printf("%s\n", str2);
13 return 0;
14 }
例4运行结果如图5所示。
图5 例4运行结果
从图5中可以看出,程序通过fscanf()函数成功读取文件中的数据,并将其格式化输出到str1和str2数组中。