文件读写
文件的打开和关闭
打开文件,fopen()
函数,返回一个文件指针
该 function 有两个参数,形参1表示路径/文件名,形参2表示打开的方式;
1
2
3
4
5
|
"r" // 只读,文件必须已存在,否则报错
"w" // 只写,创建并打开文件,若已存在则覆盖
"a" // 只写,指针移动到文件末尾,文件必须已存在,否则报错
"+" // 组合,读写
"b" // 组合,表示打开二进制文件
|
以读写方式,打开 D 盘根目录下文件 demo.txt ,保留内容,向其文件尾部追加数据:
1
2
|
FILE *fp; // 文件指针的定义
fp = fopen("D:\\demo.txt","a+");
|
打开二进制文件
1
2
|
FILE *fp;
fp = fopen("D:\\demo.txt","ab+");
|
在文件使用结束后必须关闭文件,否则会出现意想不到的错误,在 c program 中,函数 fclose() 用来关闭一个由函数 fopen() 打开的文件;该函数关闭成功返回0,否则返回非0值;
按字符读写文件
函数 fgetc() 用于从一个以只读或读写方式打开的文件上读字符;并将位置指针指向下一个字符,若成功则返回该字符,若读到文件尾则返回EOF;(EOF为符号常量,在 stdio 中定义为 -1)
函数 fputc() 用于将一个字符写到一个文件上,若写入错误返回EOF,否则返回字符C
1
|
int fputc(int c, FILE *fp); // 函数原型
|
Q1 从键盘输入一串字符,然后把它们转存到磁盘文件;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <stdio.h>
#include <stalin.h>
int main()
{
FILE *fp;
char ch;
if ((fp = fopen("demo.txt","w")) == NULL) // 判断是否为空指针,即文件打开失败后的操作
{
printf("Failure to open demo.txt!\n"); // 提示失败
exit(0); // 结束程序,这里的退出函数属于 stdlib.h
}
ch = getchar(); // 输入一个字符
while (ch != '\n') // 只要不是换行,回车
{
fputc(ch,fp); // 将该字符放入文件中;
ch = getchar(); // 再获取一个字符
}
fclose(fp); // 关闭文件
return 0;
}
|
若文件打开失败,fopen() 会返回空指针 NULL,因此可以通过检查返回值来判断文件打开是否成功。
Q2 将 0~127 之间的 ASCLL 字符写到文件中,然后从文件中读出并显示到屏幕
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
|
#include <stdio.h>
#include <stdlib.h>
int main()
{
FIEL *fp;
char ch;
fp = fopen("demo.bin","wb"); // 以二进制方式创建文件
if(fp == NULL)
{
printf("Failure to open demo.bin!\n");
exit(0);
}
for(int i = 0; i < 128; i++)
{
fputc(i,fp); // 将 ASCLL 码值在 0~127 之间的所有字符写入文件
}
fclose(fp);
// 读
if ((fp = fopen("demo.bin","rb")) == NULL)
{
printf("Error!\n");
exit(0);
}
while((ch = fgetc())!=EOF) // 一直读到文件尾
{
putchar(ch);
}
fclose(fp);
return 0;
}
|
上面标记的那一行,用来判断是否读到了文件尾,除此之外还可以使用函数 feof() 来判断是否读到文件末尾,代码如下:
1
2
3
4
5
6
|
ch = fgetc(fp);
while(!feof(fp)) // 这里feof 用于检查是否到达文件尾
{
putchar(ch);
ch = fgetc(fp);
}
|
当文件位置指针指向文件结束符(End-of-file Indicator)时,若结束返回非0值,未结束返回0值;
Q3 将上面的程序修改一下,读出的时候判断是否为可打印字符
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
|
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char ch;
int i;
fp = fopen("demo.bin","wb"); // 创建文件,以二进制形式写入
if(fp == NULL) // 判断是否打开
{
printf("Error!\n");
exit(0);
}
for(i=0; i<123; i++)
{
fputc(i,fp); // 将 i 输出到文件中;
}
fclose(fp); // 关闭文件
fp = fopen("demo.bin","rb"); // 读取文件,以二进制形式读
if(fp == NULL) // 判断是否打开
{
printf("Error!\n");
exit(0);
}
while(!feof(fp)) // 判断文件尾
{
ch = fgetc(fp)
if (!iscntrl(ch)) // 判断是否可打印
{
printf("%c\t",ch);
} else {
printf("%d\t",ch);
}
}
fclose(fp);
return 0;
}
|
两个函数的用法:
1
2
|
isprint(变量); // 如果变量可以打印显示,就返回非0值
iscntrl(变量); // 判断是否为控制字符,如果是返回0
|
读取文件中的字符串
从文件读取字符串可使用函数 fgets() ;
1
|
char *fgets(char *s, int n, FILE *fp); // 函数原型
|
该函数以 fp 所指文件读取字符串并在末尾添加\0,然后存入 s,最多读取 n-1 个字符;
当读到换行符或读满时,返回字符串首地址,即指针s,读取失败返回空指针 NULL;
ferror() 函数用来检测是否出现文件错误,若有错误返回一个非0值,否则返回0值;
将字符串写入文件的函数 fputs() ,若出现写入错误,返回EOF,否则返回一个非负数;
1
|
int fputs(const char *s, FILE *fp);
|
Q4 从键盘输入一串字符,然后把它们添加到文本文件 demo.txt 末尾。假设文件 demo.txt 已有内容 I am a student.
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
|
#include <stdio.h>
#include <stdlib.h>
#define N 80
int main()
{
FILE *fp;
char str[N];
if ((fp = fopen("demo.txt","a"))==NULL)
{
printf("Error!n");
exit(0);
}
gets(str);
fputs(str,fp);
fclose;
if((fp = fopen("demo.txt","r"))==NULL)
{
printf("Error!\n");
exit(0);
}
fgets(str,N,fp);
puts(str);
fclose(fp);
return 0;
}
|
与 gets 不同,fgets() 从指定的流读字符串,读到换行符时将换行符也作为字符串的一部分读到字符串中来;同理,与 puts buts的市场,fputs() 不会在写入文件的字符串末尾加上换行符。
c program 允许按指定格式读写文件。函数 fscanf() 用于按指定格式从文件读数据。该函数有3个参数,参数1为文件指针,参数2为格式控制参数,参数3为地址参数列表;后两个参数与函数 scanf 相同;
函数 fprintf() 用于按指定格式向文件写入数据。
Q5 编程计算每个学生的4门课程的平均分,将学生的各科成绩及平均分输出到文件 score.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
|
#include <stdio.h>
#include <stdlib.h>
#define N 30
typedef struct date {
int year;
int month;
int day;
} DATE;
typedef struct student {
long studentID;
char studentName[10];
char studentSex;
DATE birthday;
int score[4];
float aver;
} STUDENT;
void InputScore(STUDENT stu[], int n, int m);
void AverScore(STUDENT stu[], int n, int m);
void WritetoFile(STUDENT stu[], int n, int m);
int main()
{
STUDENT stu[N];
int n;
printf("How many student?");
scanf("%d",&n);
InputScore(stu,n,4);
WritetoFile(stu,n,4);
return 0;
}
|