当前位置: 首页 > news >正文

C语言文件操作全解析

一、什么是文件?

        讲文件操作之前要理解文件的概念。

        数据文件是程序运行时读/写的数据,是文件操作的对象;数据文件可以按在外存上的存储形式又划分为文本文件和二进制文件。文本文件在外存上以ASCII码的形式存储,而二进制文件(存储前不需要转换为ASCII码)在外存上以二进制的形式存储。

        举个例子,有整数10000,如果以ASCII码的形式输出到外存上,需要把每一位转化为对应的ASCII码,即 00110001 00110000 00110000 00110000 00110000,占用5个字节(每个字符一个字节),而以二进制形式输出,则只占用4个字节,即 00000000 00000000 00100111 00010000.

二、文件的打开和关闭

1.标准流

        流是一个抽象的概念,我们的输入输出操作都是通过流来完成的。C语言程序在启动时默认打开了3个流。

(1)stdin - 标准输入流,在大多数环境中从键盘输入,如 scanf 函数就是从标准输入流中读取数据

(2)stdout - 标准输出流,在大多数环境中输出至显示器界面,printf函数就是讲信息输出到标准输出流中

(3)stderr - 标准错误流,大多数环境中输出到显示器界面

2.文件指针

        stdin、stdout、stderr 三个流的类型是:FILE * ,通常称为⽂件指针。

FILE* pf;  // ⽂件指针变量

3.文件的打开和关闭

        ⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件。使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件。

// 打开⽂件 
FILE * fopen ( const char * filename, const char * mode );
// filename 表示文件名
// mode 表示文件的打开方式// 关闭⽂件,fclose不会把指针置空
int fclose ( FILE * stream );
//stream 指向要关闭的文件

4.文件的打开方式

        从上面的代码块中可看到在打开文件时,还应输入对应的打开方式,下面我们来介绍一下文件的打开方式有哪些。

        下面的输入是指从文件输入程序,同理,输出是指从程序输出到文件中。

文件打开方式含义如果指定文件不存在
"r"(只读)为了输入数据,打开一个已经存在的文本文件出错

"w"(只写)

为了输出数据,打开一个文本文件

创建一个新文件
"a"(追加)向文本文件末尾添加数据创建一个新文件
"rb"(只读)为了输入数据,打开一个二进制文件出错
"wb"(只写)为了输出数据,打开一个二进制文件创建一个新文件
"ab"(追加)向一个二进制文件末尾添加文件创建一个新文件
"r+"(读写)为了读和写,打开一个文本文件出错
"w+"(读写)为了读和写,创建一个新文件创建一个新文件
"a+"(读写)打开一个文件,在文件末尾进行读写创建一个新文件
"rb+"(读写)为了读和写,打开一个二进制文件出错
"wb+"(读写)为了读和写,新建一个新的二进制文件创建一个新文件
"ab+"(读写)打开一个二进制文件,在文件末尾进行读和写

创建一个新文件

        需要注意的是,“w”会把打开的文件的内容清空,“a”不会。

三、文件的顺序读写

        下面介绍一些顺序读写相关的函数。

函数名功能适用于
fgetc字符输入函数所有输入流
fputc字符输出函数所有输出流
fgets文本行输入函数所有输入流
fputs文本行输出函数所有输出流
fscanf格式化输入函数所有输入流
fprintf格式化输出函数所有输出流
fread二进制输入文件输入流
fwrite二进制输出文件输出流

所有输入流:文件流,标准输入流(stdin,键盘上输入)

所有输出流:文件流,标准输出流(stdout,屏幕上输出)

文件输入流:文件流

文件输出流:文件流

1.fputc

        向文件中写入内容,成功的话返回的是写入内容对应的ASCII码值,失败的话函数会返回 EOF(-1)。

int fputc ( int character, FILE * stream );//要写入的字符对应的ASCII码,指针

        举例

int main()
{//打开文件FILE* pf = fopen("test.txt","w");if (pf == NULL){perror("fopen");return 1;}//写文件for (char ch = 'a'; ch <= 'z'; ch++){fputc(ch ,pf);	//向pf指向的地址对应的文件中写入 a-z// abcdefghijklmnopqrstuvwxyz}//关闭文件fclose(pf);pf = NULL;return 0;
}

2.fgetc

        读取文件内容,成功的话函数返回被读取的字符,但会被提升为 `int` 类型;如果遇到文件末尾或者失败返回 EOF(-1)

int fgetc ( FILE * stream );//指针

        举例

int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件int ch = 0;while (( ch = fgetc(pf)) != EOF){printf("%c", ch);	//abcdefghijklmnopqrstuvwxyz}//关闭文件fclose(pf);pf = NULL;return 0;
}

3.fputs

        把 str 指向的字符串写入文件,注意 \0 不会写进去

int fputs ( const char * str, FILE * stream );

        举例

int main()
{//打开文件FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写文件fputs("hello world", pf);fputs("hello mimi", pf);//hello worldhello mimi//关闭文件fclose(pf);pf = NULL;return 0;
}

4.fgets

        从 stream 指向的文件中读出最多 num-1 个字节的数据放到 str 指向的字符串中,函数成功读取到字符,会返回指向输入缓冲区的指针 str ;遇到文件末尾或读取错误会返回 NULL。

        读出来的字符数为 num-1 是因为要在字符串最后加一个 \0

char * fgets ( char * str, int num, FILE * stream );

        举例

int main()
{//打开文件FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件char arr[10] = { 0 };fgets(arr, 10, pf);printf("%s", arr);	//hello worfgets(arr, 10, pf);printf("%s", arr);//hello worldhello m//关闭文件fclose(pf);pf = NULL;return 0;
}

5.fprintf

        格式化输出函数

int fprintf ( FILE * stream, const char * format, ... );

        举例

struct S
{char name[20];int age;float score;
};int main()
{struct S s = { "张三",20,65.5f };//想把s中的数据存放在文件中FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}//写文件 - 是以文本的形式写进去的fprintf(pf,"%s %d %f", s.name, s.age, s.score);//张三 20 65.500000fclose(pf);pf = NULL;return 0;
}

6.fscanf

        格式化输入函数

int fscanf ( FILE * stream, const char * format, ... );

        举例

int main()
{struct S s = { 0 };//想从文件test.txt中读取数据放在s中FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}//读文件fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));//打印在文件上fprintf(stdout, "%s %d %f", s.name, s.age, s.score);//printf("%s %d %f\n", s.name, s.age, s.score);//张三 20 65.500000fclose(pf);pf = NULL;return 0;
}

7.sprintf和sscanf

        sprintf - 把数据转化为字符串(不会在屏幕上输出),sscanf - 在字符串中读取格式化的数据。

int sscanf ( const char * s, const char * format, ...);int main()
{char buf[200] = { 0 };struct S s = { "张三",20,65.5f };sprintf(buf, "%s %d %f\n", s.name, s.age, s.score);printf("1.以字符串格式打印:%s\n", buf);//1.以字符串格式打印:张三 20 65.500000struct S t = { 0 };sscanf(buf,"%s %d %f", t.name, &(t.age), &(t.score));printf("2.按照格式打印    :%s %d %f\n", t.name, t.age, t.score);//2.按照格式打印    :张三 20 65.500000return 0;
}

8.fwrite

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

         ptr:指向要写什么的数组的指针;size:每个元素的长度,单位为字节;count:每次要写的元素个数;stream:写入哪里

int main()
{int arr[] = { 1,2,3,4,5,6,7 };FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen");return 1;}//写数据int sz = sizeof(arr) / sizeof(arr[0]);fwrite(arr, sizeof(arr[0]), sz, pf);	//以二进制的形式写进去fclose(pf);pf = NULL;
}

9.fread

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

        ptr:指向读取的内容存放的位置的指针,大小最小为一个数据的大小;size:每个元素的长度,单位为字节;count:每次要写的元素个数;stream:从哪里读;返回的是成功读取的元素的个数

int main()
{int arr[7] = { 0 };FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}//读数据int i = 0;while (fread(arr + i, sizeof(arr[0]), 1, pf))	//成功读到一个数据会返回1,为真;如果读完或读取失败就停止了{printf("%d ", arr[i]);i++;}//1 2 3 4 5 6 7fclose(pf);pf = NULL;
}

四、文件的随机读写

1.fseek

        根据⽂件指针的位置和偏移量来定位⽂件指针(⽂件内容的光标)

int fseek ( FILE * stream, long int offset, int origin );

stream:流
offset:偏移量,单位是字节,即一个字符大小
origin:起始位置
        (1)可以是文件的起始位置(SEEK_SET)
        (2)文件指针当前位置(SEEK_CUR)
        (3)文件末尾(SEEK_END),文件最后一个字节的下一个位置

int main()
{FILE* pf=fopen("test.txt", "r");	//test.txt中存的是abcdefgif (pf == NULL){perror("fopen");return 1;}//读文件--开始时光标在文件开始(即a)int ch=fgetc(pf);	//读完之后光标向后移动一位指向bprintf("%c", ch);	//afseek(pf,4,SEEK_CUR);	//从b开始向后数4个字节,数到fch = fgetc(pf);printf("%c", ch);	//ffclose(pf);pf = NULL;return 0;
}

2.ftell

        返回值文件指针相对于起始位置的偏移量

int fseek ( FILE * stream, long int offset, int origin );

        举例

int main()
{FILE* pf = fopen("test.txt", "r");	//test.txt中存的是abcdefgif (pf == NULL){perror("fopen");return 1;}//读文件--开始时光标在文件开始(即a)int ch = fgetc(pf);	//读完之后光标向后移动一位指向bprintf("%c", ch);	//afseek(pf, -1, SEEK_END); //如果改成0,则是文件中文本的长度printf("%d", ftell(pf)); //6fclose(pf);pf = NULL;return 0;
}

3.rewind

        让文件指针的位置回到文件的起始位置

void rewind ( FILE * stream );

五、文件结束的判定

1.ferror

ferror(pf) 是 C 语言中用于检查文件操作是否发生错误的函数
        1.  如果未发生错误,返回 0;
        2. 如果发生过错误,返回一个非 0 值

2.feof

        在⽂件读取过程中,不能⽤feof函数的返回值直接来判断⽂件的是否结束。

 feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束。

        (1)文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets)
                1)fgetc 判断是否为 EOF

                2)fgets 判断返回值是否为 NULL
        (2) 二进制文件的读取结束通过返回值是否小于实际要读的个数来判断

int feof(FILE * stream);

        如果遇到文件末尾返回一个非0值,否则返回0.

        下面以文本文件举例

#include <stdio.h>
#include <stdlib.h>
int main(void)
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perroe("fopen");return 1;}//读取int ch = 0;while ((ch = fgetc(pf)) != EOF){printf("%c\n", ch);}//判断是什么原因结束的if (feof(pf)){printf("遇到文件末尾,读取正常结束\n");}else if (ferror(pf)){perror("fgetc");}fclose(pf);pf = NULL;return 0;
}
http://www.dtcms.com/a/508646.html

相关文章:

  • 网页设计与网站建设毕业设计制作公司网站视频
  • 个人可以做几个网站吗建网站的步骤及方法
  • 怎样做网站卖自己的产品工业设计创意网站
  • 企业网站做seo的优势网站建设需要英语吗
  • 广东高端建设网站怎么样查询建设网站
  • 数据结构基石:从线性表到树形世界的探索
  • 开福区城乡建设局网站太原建网站
  • 宿州医疗网站建设泉港报名网站建设需要
  • 内蒙古乌海建设局网站郑州网站建设 易云互联
  • 算法笔记 06
  • 大模型熵-控制模型探索or利用
  • 视频教学网站开发云服务器做网站新手教程
  • 可信赖的手机网站设计百度竞价托管一月多少钱
  • Flink 1.19 REST API
  • RoniaKit QML仪表盘开发指南:从零开始创建专业仪表板
  • 版本控制与GitLab完整实践指南
  • bash 基础编程的核心语法
  • 中山品牌网站建设报价做网站首页置顶多少钱
  • 京紫元年深圳网站建设欧美风格网站特点
  • 企业网站开发制作合同wordpress禁止图片点击
  • 做英文网站2014上海画册设计
  • 美颜SDK集成实录:打造兼容多端的直播一键美颜系统
  • 资料分析-增长量
  • 网站开发种类视频号推广入口
  • 南通做网站ntwsd椒江设计公司
  • 建设l旅游网站目的及功能定位域名访问过程会不会影响网站访问
  • 做门户网站建设多少钱wordpress js调用
  • 广州企业网站设计制作佛山网站的建设
  • 网络地址转换(NAT)和ISP(互联网服务提供商)
  • a5站长网宁波建网站选哪家好点