当前位置:网站首页>C语言进阶篇 六.文件的操作
C语言进阶篇 六.文件的操作
2022-07-24 05:16:00 【且随疾风前行->】
目录
1. 为什么使用文件
2. 什么是文件
文件即指磁盘上的文件,在程序设计中,通常指两类文件:
1.程序文件
2.数据文件
3. 文件的打开和关闭
在C语言中,提供了两个函数分别用于文件的打开和关闭。
FILE*fopen(constchar*filename,constchar*mode);
参数一filename是文件名,可以用像tt.txt这样的相对路径(相对于当前工程文件的目录下),也可以用像W:\a\tt.txt这样的绝对路径(注意\前加\才能表示\字符),因为类型是字符指针,故文件名要加“ ”,表示字符串首地址。
FILE* pf = fopen("W:\\a\\tt.txt", "w");//绝对路径
FILE* pf = fopen("tt.txt", "w");//相对路径
参数二mode是指文件的打开方式,有多种打开方式,如:

该函数的返回值是FILE*类型的文件指针,事实上这是一种结构体指针,原因是文件被使用时在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个系统定义过的结构体变量中的。
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
不同编译器的FILE类型包含的内容不完全相同。当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构体的变量,并初始化。这样一来,通过文件指针就能找到对应的文件。
当使用fopen函数打开文件失败时,函数会返回空指针。
于是可以这么使用:
FILE* pf = fopen("tt.txt", "w");
if (pf == NULL) {
perror("fopen->");
return 1;
}fclose(pf);
pf = NULL;4. 文件的顺序读写
常见读写的函数

fgetc函数可以从所有输入流(包括标准输入流(键盘))中返回字符的ASCII码值,读取后该文件指针会指向文件中下一个字符。
int fgetc ( FILE * stream );
如果读到文件末尾或者读取错误就会返回EOF,这个函数和getc等效,但是有些库getc是用宏实现的。
例如工程目录下在tt.txt,写字母a,然后用fgetc可以读取文件内容


fputc函数与这个函数相对,可以将字符输出到所有输出流中(包括标准输出流(屏幕)),输出后该文件指针会指向文件中下一个字符。
int fputc ( int character, FILE * stream );
如果写入成功,返回字符的ASCII码值,写入错误时返回EOF。
与fgetc,fputc对应的一组函数是fgets,fputs,不同的是输出和输入的是字符串,
char * fgets ( char * str, int num, FILE * stream );
从stream中读取num个字符(num包含了\0,实际就num-1个字符)拷贝到str指向的空间,在字符串结尾还会拷贝一个\0,直到遇到读到换行符或者文件结尾(EOF),如果读到换行符\n,会停止,把换行符也拷贝到str指向的空间。
fgets函数和gets不太一样,首先是参数个数,然后是gets不会拷贝\0到str中,gets不能指定拷贝的字符个数(可能会导致缓冲区溢出),而fgets可以指定拷贝个数。
使用实例:



以下实例证明确实拷贝了\0

以下两个函数,fscanf可以从所有输入流中(格式化)读取数据到文件中,二fprintf则可以从所有输出流格式化输出到文件中,使用过scanf和printf这组函数就明白了,只不过把屏幕换成了文件。 对比下函数参数易于学习。
int fscanf ( FILE * stream, const char * format, ... );
int scanf ( const char * format, ... );
int sscanf ( const char * s, const char * format, ...);
int fprintf ( FILE * stream, const char * format, ... );
int printf ( const char * format, ... );
int sprintf ( char * str, const char * format, ... );
sscanf函数可以从字符串中读取格式化数据,sprintf是把格式化数据写入到字符串中。
例如:
/* sscanf example */
#include <stdio.h>
int main ()
{
char sentence []="Rudolph is 12 years old";
char str [20];
int i;
sscanf (sentence,"%s %*s %d",str,&i);
printf ("%s -> %d\n",str,i);
return 0;
}注:scanf类函数中添加了*的部分会被忽略(跳过),不会被读取,也就是说上面函数从sentence字符串中读取了Rudolph字符串到str中,然后跳过了字符串is,然后读取了12到i中。(在printf中使用,*表示用后面的形参替代*的位置,实现动态格式输出,如printf("%.*s\n", 1, "abc");从字符串“abc”输出宽度为1的字符串,结果是a)
输出如下:

注意:如果把%*s去掉则读不到12了,如下

如果调整参数顺序,结果如下:

5. 文件的随机读写
上述函数只能在文件上顺序读写数据,要实现在文件各个位置读写可以借助下列函数。
int fseek ( FILE * stream, long int offset, int origin );
这个函数可以复位文件指针,调用函数便可以让它文件指针stream指向指定的位置。
参数origin是起始位置,可以是这些参数:
offset是相对起始位置的偏移量(字节数)。
使用实例:

要得到文件指针的当前位置可以借助ftell函数
long int ftell ( FILE * stream );
该函数返回当前文件指针相对文件起始位置的偏移量(字节数)。
使用实例:

rewind函数,可以将文件指针重新指向文件的起始位置 void rewind ( FILE * stream );
例如:(文件指针指向开头,所以ftell返回0 )
6. 文本文件和二进制文件
数据文件被分成了文本文件和二进制文件两种类型。
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
通常,ptr是数组名,size是数组元素的大小(所占字节数),count是输出的元素个数,于是可以这么用,例如:

以二进制的形式打开,会发现文件中是这样的数据:

7. 文件读取结束的判定
需要注意不能用feof的返回值判断文件是否读取结束和直接判断文件是否为空。
int feof ( FILE * stream );
如果文件指针指向的位置已经没有数据了返回非0,表文件结束,否则返回0,表示还有数据。



边栏推荐
- Jetson device failed to download repository information use tips to record
- MySQL connection
- 【常用技巧】
- 求网络的flops
- The world's first large aerospace model came out. Wenxin's second supplement "Fuchun Mountain Residence map" is Baidu Pratt Whitney AI's perseverance
- [Basic 6] - encapsulation and inheritance of classes, objects and classes
- Career planning route
- 熊市抄底指南
- [deep learning] (III) image classification
- Read "effective managers - Drucker"
猜你喜欢
随机推荐
SSH service
How to avoid the most common mistakes when building a knowledge base?
Recursive cascade network: medical image registration based on unsupervised learning
Hotel IPTV digital TV system solution
Introduction to reflection
2. Input a circle radius r, when r > = 0, calculate and output the area and perimeter of the circle, otherwise, output the prompt information.
Pointer learning diary (IV) use structure and pointer (linked list)
【sklearn】数据预处理
【sklearn】RF 交叉验证 袋外数据 参数学习曲线 网格搜索
MySQL深入了解
Handwritten ORM framework
web开发
Pointer learning diary (I)
Codeforce:d2. remove the substring (hard version) [greedy string + subsequence]
The difference between compiled language and interpreted language
)的低字节来反馈给应用层或者成多种格式文档:
【sklearn】tree.DecisionTreeClassifier
Jetson device failed to download repository information use tips to record
Ia notes 2
【Pytorch】Dataset_DataLoader









