目录

一、文件和流

1、程序文件

2、数据文件

3、流

二、文件组成

三、文件的打开和关闭

1、文件的打开fopen

2、文件关闭fclose

四、文件的顺序读写

1、使用fputc和fgetc写入/读取单个字符

2、使用fputs和fgets写入/读取一串字符

3、使用fprintf和fscanf按照指定的格式写入/读取

4、使用fwrite和fread按照二进制的方式写入/读取

5、使用sprintf和sscanf将格式化数据和字符串互相转换(文件无关)

五、文件的随机读写

1、fseek(指定文件指针的位置)

2、ftell(求文件指针与起始位置的偏移量)

3、rewind(让文件指针回到起始位置)

六、文本文件和二进制文件的区别

七、文件读取结束的标志

八、文件缓冲区


一、文件和流

1、程序文件

包括源程序文件(后缀为.c)

目标文件(windows环境后缀为.obj)

可执行程序(windows环境 后缀为.exe)

2、数据文件

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

3、流

任何一个C程序,运行起来就会默认打开3个流

1、FILE* stdin(标准输入流,键盘)

2、FILE* stdout(标准输出流,显示器)

3、FILE* stderr(标准错误流,显示器)

流可以理解为输入/输出缓冲区

二、文件组成

注:文件名中不一定包含后缀名

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

FILE*就是文件指针类型,可以通过文件指针找到它指向的文件信息区(FILE类型的结构体),文件信息区用于维护一个文件(每个文件都是独立的文件信息区)

三、文件的打开和关闭

1、文件的打开fopen

filename是文件名

mode是文件打开方式

文件打开方式

含义

如果指定文件不存在

“r”(只读)

为了输入数据,打开一个已经存在的文本文件

出错

“w”(只写)

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

建立一个新的文件

“a”(追加)

向文本文件尾添加数据

建立一个新的文件

“rb”(只读)

为了输入数据,打开一个二进制文件

出错

“wb”(只写)

为了输出数据,打开一个二进制文件

建立一个新的文件

“ab”(追加)

向一个二进制文件尾添加数据

出错

“r+”(读写)

为了读和写,打开一个文本文件

出错

“w+”(读写)

为了读和写,新建一个新的文件

建立一个新的文件

“a+”(读写)

打开一个文件,在文件尾进行读写

建立一个新的文件

“rb+”(读写)

为了读和写打开一个二进制文件

出错

“wb+”(读写)

为了读和写,新建一个新的二进制文件

建立一个新的文件

“ab+”(读写)

打开一个二进制文件,在文件尾进行读和写

建立一个新的文件

2、文件关闭fclose

stream是文件指针,文件使用完后一定要fclose关闭,并把文件指针置空。(用起来像free)

int main()
{FILE* pf = fopen("test.txt", "r");//文件路径可以是相对路径或绝对路径if (pf == NULL){printf("%s\n", strerror(errno));exit(-1);}fclose(pf);//不关闭文件可能会造成数据丢失pf = NULL;return 0;
}

四、文件的顺序读写

字符输入函数

fgetc

所有输入流

字符输出函数

fputc

所有输出流

文本行输入函数

fgets

所有输入流

文本行输出函数

fputs

所有输出流

格式化输入函数

fscanf

所有输入流

格式化输出函数

fprintf

所有输出流

二进制输入

fread

文件

二进制输出

fwrite

文件

1、使用fputc和fgetc写入/读取单个字符

写入单个字符到文件

character:要写入的字符

stream:指向输出流 FILE 对象的指针。

int main()
{FILE* pf = fopen("test.txt", "w");//文件路径可以是相对路径或绝对路径if (pf == NULL){printf("%s\n", strerror(errno));//perror("fopen");//void perror ( const char * str )用来将上一个函数发生错误的原因输出到标准设备(stderr)exit(-1);}for (char i = 'a'; i <= 'z'; i++){fputc(i, pf);//输出}fclose(pf);pf = NULL;
}

读取文件中的单个字符

stream:指向输入流 FILE 对象的指针。

int main()
{pf = fopen("test.txt", "r");//文件路径可以是相对路径或绝对路径if (pf == NULL){printf("%s\n", strerror(errno));exit(-1);}printf("%c\n", fgetc(pf));//输入,也可以写一个循环读取printf("%c\n", fgetc(pf));printf("%c\n", fgetc(pf));printf("%c\n", fgetc(pf));printf("%c\n", fgetc(pf));fclose(pf);pf = NULL;return 0;
}

2、使用fputs和fgets写入/读取一串字符

写入一串字符到文件

str:要写入的字符串的地址

stream:指向输出流 FILE 对象的指针。

int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen:");exit(-1);}char arr[] = "abcde";//test.txt文件被写入abcdefputs(arr, pf);fclose(pf);pf = NULL;return 0;
}

读取文件中num个字符

str:读到的字符串放到str指向的空间里去

num:读取num-1个字符,并补上\0

stream:指向输入流 FILE 对象的指针。

读取成功:返回str的地址

读取失败或错误:返回空指针

监视发现,我们从文件中读取5个字符,实际只读了4个,最后一个补了\0

3、使用fprintf和fscanf按照指定的格式写入/读取

stream:指向输出流 FILE 对象的指针。

后续参数使用方法与printf一样

struct S
{char name[20];int tele;float scores;
};
int main()
{struct S s = { "zhangsan",1510,66.5f };FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen:");exit(-1);}fprintf(pf, "%s %d %f", s.name, s.tele, s.scores);//打印到txt文件fprintf(stdout, "%s %d %f", s.name, s.tele, s.scores);//打印到屏幕fclose(pf);pf = NULL;return 0;
}

stream:指向输入流 FILE 对象的指针。

后续参数使用方法和scanf一样

struct S
{char name[20];int tele;float scores;
};
int main()
{struct S s = { 0 };FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen:");exit(-1);}fscanf(pf, "%s %d %f", s.name, &s.tele, &s.scores);//将文件中的内容读取到结构体中printf("%s %d %f", s.name, s.tele, s.scores);fclose(pf);pf = NULL;return 0;
}

4、使用fwrite和fread按照二进制的方式写入/读取

ptr:从ptr指向的当前位置开始写入

size:每个元素的大小

count:要写入的元素个数

stream:指向输出流 FILE 对象的指针。

struct S
{char name[20];int tele;float scores;
};
int main()
{struct S s = { "zhangsan",1510,66.5f };FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror("fopen:");exit(-1);}fwrite(&s, sizeof(struct S), 1, pf);fclose(pf);pf = NULL;return 0;
}

fread参数和fwrite一样

ptr:从ptr指向的当前位置开始读取

struct S
{char name[20];int tele;float scores;
};
int main()
{struct S s = { 0 };FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen:");exit(-1);}fread(&s, sizeof(struct S), 1, pf);printf("%s %d %f", s.name, s.tele, s.scores);fclose(pf);pf = NULL;return 0;
}

5、使用sprintf和sscanf将格式化数据和字符串互相转换(文件无关)

将格式化数据转换为字符串

str:将格式化数据放到目标地址

后续参数和使用方式和printf一样

struct S
{char name[20];int tele;float scores;
};
int main()
{struct S s = { "zhangsan",1510,66.5f };char arr[60]={0};sprintf(arr, "%s %d %f", s.name, s.tele, s.scores);printf("%s", arr);return 0;
}

将字符串转换为格式化数据

s:指向字符串的指针

后续参数和使用方式和scanf一样

struct S
{char name[20];int tele;float scores;
};
int main()
{struct S s = { 0 };char arr[60]={ "zhangsan 1510 66.5f" };sscanf(arr, "%s %d %f", s.name, &s.tele,&s.scores);printf("%s %d %f", s.name,s.tele,s.scores );return 0;
}

五、文件的随机读写

1、fseek(指定文件指针的位置)

注意:每次文件读取完毕后,文件指针++

stream:指向标识流的 FILE 对象的指针

offset:指针偏移量

origin:指针起始点,如下图:

SEEK_SET

文件开头

SEEK_CUR

文件指针的当前所处的位置

SEEK_END

文件结尾

int main()
{FILE* pf = fopen("test.txt", "r+");if (pf == NULL){perror("fopen:");exit(-1);}fputs("abcde", pf);fseek(pf, 2, SEEK_SET);int ch = fgetc(pf);//该语句执行完毕后,指针++,指向dprintf("%c ", ch);//打印cfseek(pf, 0, SEEK_CUR);ch = fgetc(pf); //该语句执行完毕后,指针++,指向eprintf("%c ", ch);//打印dfseek(pf, -1, SEEK_END);//这里SEEK_END是指向e的后一个ch = fgetc(pf);//该语句执行完毕后,指针++,指向e的后一个printf("%c ", ch);//打印efclose(pf);pf = NULL;return 0;
}

2、ftell(求文件指针与起始位置的偏移量)

int main()
{FILE* pf = fopen("test.txt", "r+");if (pf == NULL){perror("fopen:");exit(-1);}fputs("abcde", pf);fseek(pf, -1, SEEK_END);//这里SEEK_END是指向e的后一个int ch = fgetc(pf);//该语句执行完毕后,指针++,指向e的后一个printf("%c ", ch);//打印eprintf("%d", ftell(pf));//打印5,当前指针在e的后一个,相对于a相差5fclose(pf);pf = NULL;return 0;
}

3、rewind(让文件指针回到起始位置)

六、文本文件和二进制文件的区别

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。 字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

七、文件读取结束的标志

文本文件读取是否结束,fgetc判断返回值是否为 EOF . fgets判断返回值是否为 NULL

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

feof:判断文件是否读到末尾而结束,返回值为真,就是读到了文件结束

ferror:判断文件是否读取错误而结束,返回值为真,就是文件读取遇到了错误

八、文件缓冲区

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。

从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。

如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

【C语言】文件相关函数详解相关推荐

  1. C语言文件操作详解【收藏】

    C语言中没有输入输出语句,所有的输入输出功能都用 ANSI C提供的一组标准库函数来实现.文件操作标准库函数有: 「文件的打开操作」 fopen 打开一个文件 「文件的关闭操作」 fclose 关闭一 ...

  2. C 和 C++ 文件操作详解

    来源:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551662.html 来源:http://www.cnblogs.com/likebet ...

  3. c语言 recv_sin,C++_C语言中经socket接收数据的相关函数详解,recv()函数: 头文件:#incl - phpStudy...

    C语言中经socket接收数据的相关函数详解 recv()函数:头文件: #include #include 定义函数: int recv(int s, void *buf, int len, uns ...

  4. c语言练习题及答案)(1),c语言练习题(带详解答案)1.pdf

    c语言练习题(带详解答案)1 (-2) -1: 一单项选择题 /为求商运算符,该运算符能够对整型.字符.浮点等类型的数 据进行运算,5/2 2 1.(A )是构成C语言程序的基本单位. 11.如果 i ...

  5. python语言的格式框架_django框架模板语言使用方法详解

    本文实例讲述了django框架模板语言使用方法.分享给大家供大家参考,具体如下: 模板功能 作用:生成html界面内容,模版致力于界面如何显示,而不是程序逻辑.模板不仅仅是一个html文件,还包括了页 ...

  6. C语言再学习 -- 详解C++/C 面试题 2

    (经典)C语言测试:想成为嵌入式程序员应知道的0x10个基本问题. 参看:嵌入式程序员面试问题集锦 1.用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define ...

  7. linux mk创建文件,Linux运维知识之Linux mkkickstart建立安装的组态文件命令详解

    本文主要向大家介绍了Linux运维知识之Linux mkkickstart建立安装的组态文件命令详解,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助. 功能说明:建立安装的组态文件 ...

  8. python setting.py_python基础教程:Django框架的中的setting.py文件说明详解

    这篇文章主要介绍了Django框架的中的setting.py文件说明详解,这个文件包含了所有有关这个Django项目的配置信息,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.加载数据库,数据库 ...

  9. 一个简单的C语言程序(详解)

    C Primer Plus之一个简单的C语言程序(详解) #include <stdio.h>int main(void) //一个简单的 C程序 {int num; //定义一个名为 n ...

最新文章

  1. QQ浏览器怎样在首页显示优先推荐的网站
  2. 股市心态决定成败:不贪不惧不急不赌
  3. oracle log 分析程序,oracle之logminer日志分析
  4. -矩阵-创建矩阵-简单方法
  5. linux web故障,网络故障处理与优化 linux服务器配置及故障排除 项目9 配置与管理web服务器.docx...
  6. 《自拍教程47》Python adb重启设备100次
  7. Unity设置鼠标指针图片
  8. Idea使用SVN下载运行项目
  9. 计算机复制教程,介绍几款常用的屏幕拷贝工具,快速抓取电脑画面
  10. ubuntu18.04下EnlightenGAN运行过程记录
  11. 今日头条号如何过原创
  12. mysql 去掉前面的0_去掉前面的0的sql语句(前导零,零前缀)
  13. VS2010安装Visual Assist X
  14. 0x800700E1: 无法成功完成操作,因为文件包含病毒 解决方法
  15. hdoj4550 威威猫系列故事——打地鼠(java版)
  16. element-ui中导航菜单默认激活子菜单的第一项
  17. 分享proj4js中经纬度和兰伯特投影的转换代码
  18. 基于Web的图书管理系统设计与实现(附源码地址)
  19. 微信新玩法,只需三步就可以在朋友圈发送竖排文字,好看又酷炫!
  20. 如何在百度地图开发平台获取开发者Key(AK)

热门文章

  1. 射击小游戏源码《90坦克大战》源码H5+安卓+IOS三端源码
  2. 从底层彻底重做一个Window10Ubuntu双系统
  3. Flink CDC入门实践--基于 Flink CDC 构建 MySQL 和 Postgres 的 Streaming ETL
  4. Flink CDC 实战
  5. kombu.exceptions.EncodeError: Object of type NewUser is not JSON serializable
  6. 用matlab 实现向量范数和矩阵范数
  7. mysql删除表中内容_SQL中删除表中的内容
  8. TREK电源维修trek高压发生器维修610D
  9. 中医的肝指的是哪里?
  10. 图片格式怎么转换?这两招帮你快速修改图片格式