c语言 文件操作


在使用通讯录时,数据在程序结束的一刻销毁,为了数据的持久化,通常会使用文件操作。

1.文件打开与关闭

每个被使用的文件会在内存中创建一个文件信息区,保存文件的相关信息与一个文件结构体中,该结构体是系统声明的名为FILE。通过一个文件指针就能修改文件的信息。
在这里插入图片描述
用fopen函数打开文件,并且返回该文件的指针,filename为文件名,mode为文件打开方式在这里插入图片描述
关闭文件用函数fclose,参数是文件名,关闭完置空指针。
在这里插入图片描述
打开与关闭的代码
在这里插入图片描述
如果打开的文件不在当前项目文件的路径下,需要写一个完整路径,但是斜杠会被当作转义字符,写两个斜杠来表示一个斜杠,防止转义
在这里插入图片描述

2.文件顺序读写

在这里插入图片描述

1.fputc

在这里插入图片描述
fputc,写数据到流中,c是要写的字符,stream是指向流的指针
在这里插入图片描述
pf改成stdout,表示标准输出流,输出数据到屏幕上
在这里插入图片描述

2.fgetc

在这里插入图片描述
fgetc,从流中读取字符,返回该字符的ASCII码值。
0,text_Q1NETiBALlNhY2FKYXdlYQ==,size_20,color_FFFFFF,t_70,g_se,x_16)

用fgetc,ret能得到文件中的数据。在这里插入图片描述

3.fgets

在这里插入图片描述
fgets读取文件中的字符串,注意\0也会被当做一个字符读取。n是读取的最大字符数,\0会占一个字符。流中的数据会读取到string字符串中。
在这里插入图片描述

4.fputs

在这里插入图片描述
fputs直接写一串字符到流中

在这里插入图片描述

5.fscanf

在这里插入图片描述
fscanf,从流中读取数据,scanf读取数据的流是标准输入流stdin。
在这里插入图片描述
从pf的文件流中读取数据到str中。而scanf是从键盘(标准输入流)中读取数据到变量中。

6.fprintf

在这里插入图片描述
写数据到流中,printf是写数据到标准输出流,也就是屏幕中。用fprintf能写数据到文件流中。
在这里插入图片描述
把str的数据写入到pf的文件流中。而printf是把str的数据写入到屏幕。

7.fread

和fscanf类似,fread读取数据从一个流中
在这里插入图片描述
buffer用来存储数据,size是数据类型的字节数,count数据的个数,stream是要读取的流。
在这里插入图片描述

8.fwrite

将数据以二进制的形式写到流中
在这里插入图片描述
buffer是数据的源头,size数据类型的大小,count数据的个数,stream数据存储的目的地。
在这里插入图片描述
如果写的数据是字符,文本是看得懂的。

3.scanf/sscanf/fscanf和print/sprintf/fprintf对比

1.scanf针对标准输入流的格式化输入语句,从标准输入流中读取数据
2.fscanf针对所有输入流的格式化输入语句,也就是说能从文件流中读取数据
3.sscanf则是从字符串中读取数据,针对字符串的格式化输入语句
在这里插入图片描述
读取buffer的数据以格式化的形式输入到变量中。
在这里插入图片描述
1.printf针对标准输出流的格式化输出语句,一般都输出到屏幕上
2.fprintf针对所有输出流的格式化输出语句,还能输出到文件流中
3.sprintf将格式化的数据输出到字符串中
在这里插入图片描述
将参数中的数据输出到buffer中。
在这里插入图片描述

4.文件的随机读写

4.1fseek

在这里插入图片描述
调整文件指针。stream是打开文件后产生的文件指针,offset是距离初始位置的偏移量,而origin偏移量有三个值
在这里插入图片描述
SEEK_CUR是当前指针指向的位置
SEEK_END是文件的末尾位置
SEEK_SET是文件的开始位置
在这里插入图片描述
读取文件两次后指针会向后偏移两次,指向了l,但用fseek将文件指针指向文件开始处,再次打印结果为h

4.2ftell

在这里插入图片描述
参数是文件指针,返回其中的文件指针偏移量
在这里插入图片描述

4.3rewind

在这里插入图片描述
将指针调整到最初位置
在这里插入图片描述

5.文本文件与二进制文件

字符在内存中以ASCII码的形式存储,数值型数据能以ASCII码形式存储,也能以二进制形式存储。直接以二进制形式存储的文件是二进制文件,加以转换存储的文件是文本文件

在这里插入图片描述
10000以二进制形式存储,占用内存大小是4字节,以文本形式存储,占用大小是5字节(分别将每一位上的数字转换成ASCII码存储)。

6.文件读取结束的判定

不能用feof来判断文件是是否读取结束,feof是用来判断文件读取结束时,其结束原因,是遇到文件尾还是读取失败。

int main(void)
{
    int c; // 注意:int,非char,要求处理EOF
    FILE* fp = fopen("test.txt", "r");
    if(!fp) {
        perror("File opening failed");
        return EXIT_FAILURE;
   }
 //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
   { 
       putchar(c);
   }
//判断是什么原因结束的
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
    fclose(fp);
}

fgetc在文件读取失败或文件结束时返回EOF,fgets则返回空指针

二进制文件

enum { SIZE = 5 };
int main(void)
{
    double a[SIZE] = {1.,2.,3.,4.,5.};
    FILE *fp = fopen("test.bin", "wb"); // 必须用二进制模式
    fwrite(a, sizeof *a, SIZE, fp); // 写 double 的数组
    fclose(fp);
    double b[SIZE];
    fp = fopen("test.bin","rb");
    size_t ret_code = fread(b, sizeof *b, SIZE, fp); // 读 double 的数组
    if(ret_code == SIZE) {
        puts("Array read successfully, contents: ");
        for(int n = 0; n < SIZE; ++n) printf("%f ", b[n]);
        putchar('\n');
   } else { // error handling
       if (feof(fp))
          printf("Error reading test.bin: unexpected end of file\n");
       else if (ferror(fp)) {
           perror("Error reading test.bin");
       }
   }
    fclose(fp);
}

fread函数返回读取到的元素个数,用其返回值与实际要读的元素个数比较。

7.文件缓冲区

系统自动在内存中为每一个使用的文件开辟一块缓存区,将文件数据输入到磁盘中,要先装满缓冲区,缓冲区才会将数据写入到磁盘。从磁盘中读取数据元素同样。

所有在写文件时,如果想对刚刚写下的数据进行操作,必须刷新缓存区,用fflush函数,否则直接对数据进行操作很可能出现错误。

在文件结束时,缓冲区也会自动刷新。

int main()
{
 FILE*pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先将代码放在输出缓冲区
 printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
 Sleep(10000);
 printf("刷新缓冲区\n");
 fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
 //注:fflush 在高版本的VS上不能使用了
 printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在关闭文件的时候,也会刷新缓冲区
 pf = NULL;
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值