文件指针
用一个称为文件指针的指针变量指向文件,通过文件指针就可对它所指向的文件进行各种操作。
声明文件指针的简单形式:
FILE是结构体类型struct _iobuf的同义词,结构体类型struct _iobuf在头文件stdio.h中声明,用于描述文件的相关信息。
打开和关闭文件
文件在进行读写操作之前要先打开,使用完毕要关闭。所谓打开文件,实际上是获取文件的有关信息,并使文件指针指向该文件,以便进行相关操作。关闭文件则断开指针与文件之间的联系。
打开文件
库函数fopen用来打开一个文件,要使用库函数fopen,需包含头文件stdio.h。函数调用的形式:
1
| 文件指针名 = fopen(文件名, 使用文件方式);
|
例如:
1
| fp1 = ("data.txt", "r");
|
功能:打开当前目录下的文件data.txt,只允许进行“读”操作,并使文件指针fp1指向文件data.txt。
1
| FILE *fp2 = fopen("C:\\info.dat", "rb");
|
功能:打开C驱动器磁盘的根目录下的文件info.dat,按二进制方式进行读操作,并使文件指针fp2指向文件info.dat。
字符 |
含义 |
r |
读(read) |
w |
写(write) |
a |
追加(append) |
t |
文本文件(text),可省略不写 |
b |
二进制文件(banary) |
+ |
读和写 |
组合 |
含义 |
rt 或 r |
只读打开一个文本文件,只允许读数据 |
wt 或 w |
打开或创立一个文件文件,只允许写数据 |
at 或 a |
追加打开一个文本文件,并在文件末尾写数据 |
rb |
只读打开一个二进制文件,只允许读数据 |
wb |
打开或建立一个二进制文件,只允许写数据 |
ab |
追加打开一个二进制文件,并在文件末尾写数据 |
关于使用文件方式有以下几点说明
关闭文件
文件一旦使用完毕,应调用库函数fclose关闭文件,以避免数据丢失等错误。要使用库函数fclose,需包含头文件stdio.h。函数调用的形式:
文件的读写操作
字符读写库函数
- 库函数fputc
函数调用的形式:
功能:将一个字符写入文件指针指向的文件中。例如:
将“?”写入fp指向的文件中。
- 库函数fgetc
函数调用的形式:
功能:从文件指针指向的文件中读取一个字符并返回,如果文件已结束,则返回EOF。
例题
输入一行字符,写入文件 data.txt ,读取并输出文件 data.txt 的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fp; char ch; fp = fopen("data.txt", "w"); printf("Input a string: "); scanf("%c", &ch); while(ch != '\n') { fputc(ch, fp); scanf("%c", &ch); } fclose(fp); fp = fopen("data.txt", "r"); ch = fgetc(fp); while(ch != EOF) { printf("%c", ch); ch = fgetc(fp); } printf("\n"); fclose(fp); return 0; }
|
运行结果:
1 2
| Input a string: Programming Language C Programming Language C
|
写入文件完成,文件的当前位置移到文件尾,关闭文件,读取文件之前再重新打开文件,使文件的当前位置移到文件头,以读取数据。
字符串读写库函数
- 库函数fputs
函数调用的形式:
功能:将字符串写入文件指针所指向的文件中,不写入’\0’。
- 库函数 fgets
函数调用的形式:
1
| fgets(数组元素的类型为char的数组名, 整数n, 文件指针);
|
功能:从文件指针指向的文件中读取最多n - 1个字符,并存储到数组中,遇到换行符(读取并存入数组)或文件结束标志,读取结束。在最后一个字符存入数组后,还要向数组中存入一个’\0’,以构成一个字符串。
编程练习1
输入一行字符,将其中的小写字母转换为大写字母,其他字符保持不变,将转换后的内容写入文件 data1.txt 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <stdio.h> int main(void) { FILE *fp; char ch; fp = fopen("data1.txt", "w"); printf("请输入一行字符:"); scanf("%c", &ch); while(ch != '\n') { if(ch >= 'a' && ch <= 'z') { ch -= 32; } fputc(ch, fp); scanf("%c", &ch); } fclose(fp); fp = fopen("data1.txt", "r"); ch = fgetc(fp); while(ch != EOF) { printf("%c", ch); ch = fgetc(fp); } printf("\n"); fclose(fp); return 0; }
|
运行结果:
编程练习2
读取文件data1.txt 的内容,将其中的大写字母转换为小写字母,其他的字符不变,将转换后的内容输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <stdio.h> int main(void) { FILE *fp; fp = fopen("data1.txt", "r"); char ch; ch = fgetc(fp); while(ch != EOF) { if(ch >= 'A' && ch <= 'Z') { printf("%c", ch + 32); } else { printf("%c", ch); } ch = fgetc(fp); } printf("\n"); fclose(fp); return 0; }
|
运行结果:
编程练习3
描述学生的结构体类型 struct student 的声明如下:
1 2 3 4 5 6 7 8
| struct student { char sno[8]; char name[20]; char sex; int age; double score; };
|
输入这五个学生的信息,并写入文件 data2.txt 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include <stdio.h> struct student { char sno[8]; char name[20]; char sex; int age; double score; }; int main(void) { FILE *fp; struct student s[5]; struct student t[5]; int i; for(i = 0;i < 5;i ++) { printf("请输入第%d个学生的信息:\n", i + 1); if(i != 0) { getchar(); } printf("性别(男:M 女:F):"); scanf("%c", &s[i].sex); printf("学号:"); scanf("%s", s[i].sno); printf("姓名:"); scanf("%s", s[i].name); printf("年龄:"); scanf("%d", &s[i].age); printf("分数:"); scanf("%lf", &s[i].score); } fp = fopen("data2.txt", "w"); for(i = 0;i < 5;i ++) { fprintf(fp, "%c %s %s %d %lf\n", s[i].sex, s[i].sno, s[i].name, s[i].age, s[i].score); } fclose(fp); fp = fopen("data2.txt", "r"); printf(" sno\t\tname\t\tsex\t\tage\t\tscore\n"); for(i = 0;i < 5;i ++) { fscanf(fp, "%c%s%s%d%lf", &t[i].sex, t[i].sno, t[i].name, &t[i].age, &t[i].score); fgetc(fp); printf("%s\t\t%s\t\t%c\t\t%d\t\t%.1lf\n", t[i].sno, t[i].name, t[i].sex, t[i].age, t[i].score); } fclose(fp); return 0; }
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| 请输入第1个学生的信息: 性别(男:M 女:F):M 学号:2018001 姓名:猫七 年龄:24 分数:96 请输入第2个学生的信息: 性别(男:M 女:F):F 学号:2018002 姓名:老六 年龄:25 分数:99 请输入第3个学生的信息: 性别(男:M 女:F):M 学号:2018003 姓名:苏晗 年龄:28 分数:94 请输入第4个学生的信息: 性别(男:M 女:F):M 学号:2018004 姓名:韩星星 年龄:23 分数:92 请输入第5个学生的信息: 性别(男:M 女:F):F 学号:2018005 姓名:阿么 年龄:25 分数:89
|
编程练习4
读取文件 data2.txt 的内容,计算平均分并输出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <stdio.h> struct student { char sno[8]; char name[20]; char sex; int age; double score; }; int main(void) { FILE *fp; struct student s[5]; fp = fopen("data2.txt", "r"); double sum = 0.0, average = 0.0; int i; for(i = 0;i < 5;i ++) { fscanf(fp, "%c %s %s %d %lf", &s[i].sex, s[i].sno, s[i].name, &s[i].age, &s[i].score); fgetc(fp); sum += s[i].score; } fclose(fp); average = sum / 5; printf("average = %.2lf\n", average); return 0; }
|
运行结果: