C 语言文件操作笔记分享

文件

磁盘上的文件是文件。 但是在程序设计中, 我们一般谈的文件有两种:程序文件、数据文件


一、文件种类

文件名包含3部分:文件路径 + 文件名主干 + 文件后缀

程序文件

包括源程序文件(后缀为.c), 目标文件(windows环境后缀为.obj)可
执行程序(windows环境后缀为.exe)。

数据文件

文件的内容不一定是程序, 而是程序运行时读写的数据,
比如程序运行需要从中读取数据的文件, 或者输出内容的文件。

文件类型

根据数据的组织形式, 数据文件被称为文本文件或者二进制文件。
数据在内存中以二进制的形式存储, 如果不加转换的输出到外存, 就是二进制文件。

如果要求在外存上以ASCII码的形式存储, 则需要在存储前转换。以ASCI字符的形式存储的文件就是文本文件。

文件缓冲区

ANSIC标准采用”缓冲文件系统"处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在
使用的文件开辟一块"文件缓冲区"。 从内存向磁盘输出数据会先送到内存中的缓冲区, 装满缓冲区后才 - 起送到磁盘
上。如果从磁盘向计算机读入数据, 则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区), 然后再从缓冲区逐
个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的

图解

在这里插入图片描述

文件指针

缓冲文件系统中, 关键的概念是“文件类型指针”, 简称"文件指针"。
每个被使用的文件都在内存中开辟了一个相应的文件信息区, 用来存放文件的相关信息(如文件的名字, 文件状态及
文件当前的位置等)。这些信息是保存在一个结构体变量中的。 该结构体类型是有系统声明的, 取名FILE

文件使用方式

图解

在这里插入图片描述

文件顺序读写

图解

在这里插入图片描述

二. 函数使用

定义pf是一个指向FILE类型数据的指针变量。 可以使pf(维护)指向某个文件的文件信息区(是一个结构体变量)。 通过该文
件信息区中的信息就能够访问该文件。也就是说, 通过文件指针变量能够找到与它关联的文件。


字符输入输出函数(一个字符一个字符写和读)

写 fputc(函数)

路径可以写可以不写,写了就是绝对路径没有写,表示(相对路径)该项目目录下
/* fopen(“C:\Vstiod\test. txt”,“r”);*/

   // 写fputc(写)
    FILE* pfWrite = fopen(" test. txt", "w");//文件输出流
         if (pfWrite == NULL) {
             printf("%s\n",strerror(errno));//strerror根据系统报
             //的状态码进行反馈信息
             return 0;
         }
     //写文件
     fputc('A',pfWrite); 
      fputc('l',pfWrite);
     fputc('i',pfWrite);
      fputc('c',pfWrite);
      fputc('e',pfWrite);
     //关闭文件
     fclose(pfWrite);
     pfWrite = NULL;

读fgetc(函数)

 FILE* pfRead = fopen(" TEST. txt", "r");//文件输入流
    if (pfRead == NULL) {
        printf("%s\n", strerror(errno));
        //
        return 0;
    }
    //读文件
   //读文件|
    printf(" %c", fgetc(pfRead));
    printf(" %c", fgetc(pfRead));
    printf(" %c", fgetc(pfRead));
    

    //关闭文件
    fclose(pfRead);
    pfRead = NULL;

从键盘输入
输出到屏幕.
键盘&屏幕都是外部设备

键盘-标准输入设备|stdin
屏幕-标准输出设备|stdout
是一个程序默认打开的两个流设备

    stdin FILE*
    stdout FILE*
    stderr FILE*
 //键盘输入屏幕输出
    int ch = fgetc(stdin);//键盘上输入
    fputc(ch, stdout);//屏幕上输出
    return 0;

文本输入输出函数(一行一行读和读)

fgets函数(一次读取一行)

//fgets//函数(一次读取一行)
    char buf[1024] = { 0 };
    FILE* pf = fopen("test.txt", "r");
        if (pf == NULL)
        {

            return 0;
        }
    //读文件
    fgets(buf, 1024, pf);//通过pf文件指针读到的数据放到buf里,读取1024个
    //printf("%s", buf);//有自己的换行
   
    
    //puts函数打印到标准流屏幕
    puts(buf);//写一行到标准流,//有自己的换行
    fgets(buf, 1024, pf);
    //printf("%s", buf);//有自己的换行
    puts(buf);
    fclose(pf);
    pf = NULL;

fputs函数(写)

 char buf[1024] = { 0 };
    FILE* pf = fopen("test.txt", "w");
    if (pf == NULL)
    {
        return 0;
    }
    //写文件
    fputs("hello\n", pf);//写一行。没有换行
    fputs("world\n", pf);
    fclose(pf);
    pf = NULL;
    return 0;
 //从键盘读取一-行文本信息
    char buf[1024] = { 0 };
    //fgets(buf, 1024, stdin);//从标准输入流读取
    //fputs(buf, stdout);//输出到标准输出流
    gets(buf);//键盘读取一行
    puts(buf);//屏幕输出一行这两个和上面是等价的

fprintf(格式化输出函数)

在这里插入代码片
struct S{
      int n;
    float score;
    char arr[10];
};

 int main() {

struct S s = { 19, 238.234, "Alice" };
FILE* pf = fopen("test.txt", "w");
if (pf == NULL){
return 0;


}
//格式化的形式写文件
//格式化的形式写文件
fprintf(pf, "%d %f %s", s.n, s.score, s.arr);//(要写的文件流,格式,数据)
fclose(pf);
pf = NULL;
return 0;





//格式化输入函数(读)
//fscanf
struct S s = { 0};//把读取到的数据放到这里
FILE* pf = fopen("test.txt", "r");
if (pf == NULL) {
    return 0;


}
//格式化的形式输入数据
fscanf(pf, "%d %f %s", &(s.n), &(s.score), s.arr);//(要读的文件流,格式,读取的数据放哪里)
printf("%d %f %s\n", s.n, s.score, s.arr);//打印
fclose(pf);
pf = NULL;


//标准输入和输出
fscanf(stdin, "%d %f %s", &(s.n), &(s.score), s.arr);
fprintf(stdout, "%d %f %s", s.n, s.score, s.arr);
}


数据类型转换成字符串sprintf函数

/数据类型转换成字符串sprintf函数
struct S s = { 100, 3.14f, "abcdef" };
struct S tmp = { 0};
char buf[1024] = { 0 };
sprintf(buf, "%d %f %s", s.n, s.score, s.arr);//转换好的字符串存入buf
printf("%s\n", buf);
//从buf里放的字符串的数据以格式化的形式放入到tmp中
sscanf(buf, "%d %f %s", &(s.n), &(s.score), &(s.arr));
printf("%d %f %s", tmp.n, tmp.score, tmp.arr);


return 0;

二进制写文件

二进制写文件fwrite函数

struct S s = { 100, 3.14f, "abcdef" };
structStmp = { 0 };
FILE* pf = fopen("test. txt", "wb");
if (pf == NULL)
{
    return 0;
    //二进制的形式写文件
    fwrite(&s, sizeof(struct S), 1, pf);//数据,写一个,写入文件流里
    fclose(pf);
    pf = NULL;

二进制读文件

structStmp = { 0 };
FILE* pf = fopen("test. txt", "rb");
if (pf == NULL)
{
    return 0;
}
//二进制的形式读文件
fread(&tmp, sizeof(struct S), 1, pf);//&tmp要有能力存放1个数据的大小
printf("%s %d %lf\n", tmp.n, tmp.score, tmp.arr);(放入的地址,读几个,读取的文件流)
fclose(pf);
pf = NULL;
return 0;

三. 文件的随机读取

fseek函数(定位文件指针)

fseek(文件流,偏移量(以这偏移量(字节)),文件指针的当前位置(当前位置为起点))
SEEK_CUR//文件当前位置
SEEK_END//文件末尾
SEEK_SET//文件起始位置

FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
	return 0;
}
	//1.定位文件指针
	fseek(pf, 2, SEEK_CUR);
	//2.读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	//读完一个指针,指针向前偏移
	//ftell(函数)
	int pos = ftell(pf);//文件指针相当于起始位置的偏移量
	rewind(pf);//让文件指针会到起始位置
	printf("%d\n",pos);
		

	fclose(pf);
	pf = NULL;

文件结束判定

被错误使用的feof
牢记 : 在文件读取过程中, 不能用feof函数的返回值直接用来判断文件的是否结束。
而是应用于当文件读取结束的时候, 判断是读取失败结束, 还是遇到文件尾结束。*/
1 .文本文件读取是否结束, 判断返回值是否为EOF(fgetc), 或者NULL(fgets)
例如:
fgetc判断是否为EOF.
fgets判断返回值是否为NULL.

2 进制文件的读取结束判断, 判断返回值是否小于实际要读的个数。
例如 :。fread判断返回值是否小于实际要读的个数。

FILE* pf = fopen("test.txt", "r");
    if (pf == NULL) {
        return 0;
    }
    int ch = fgetc(pf);
    printf("%d\n", ch);//-1 //EOF=-1
    fclose(pf);
    pf = NULL;

ferror()函数检测流是不是有错误

函数原型:int ferror(FILE * stream)
它的一般调用形式为 ferror(fp);如果ferror返回值为0(假),
表示未出错。如果返回一个非零值,
表示出错。应该注意,对同一个文件 每一次调用输入输出函数
,均产生一个新的ferror函 数值,因此,应当在调用一个输入输出函数后立即
检 查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。

if (ferror(pf))
{
    printf("读取文件:file.txt 时发生错误\n");
      //perror("hehe");//hehe:No such file or directory//报错信息可自定义
}
else if (feof(pf)){//判断是不是遇到了END
    printf("end of file\n");
}
fclose(pf);
pf = NULL;
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值