第十五课 文件读写

文件读写

文件的打开和关闭

打开文件,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;
}
Licensed under CC BY-NC-SA 4.0
本文阅读量 次, 总访问量 ,总访客数
Built with Hugo .   Theme Stack designed by Jimmy