C语言库函数中文件读写操作精讲

这篇博客详细讲解了C语言中文件读写操作,包括fopen、fclose、fgets/fputs、fscanf/fprintf、fread/fwrite等函数的使用。区分了文本模式和二进制模式的区别,特别是在换行符处理和结构化数据读写上的差异。此外,还介绍了其他如fseek和rewind等文件操作函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


这篇文章主要解决如下几个问题:

  • C语言中如何进行文件读写?
  • fopen时的文本模式和二进制模式有什么区别?
  • fread、fgets和fscanf各有什么区别,如何使用?
  • fwrite、fputs和fprintf各有什么区别,如何使用?

概述

在C语言中进行文件操作,可以使用C库提供的文件读写库函数。我们经常使用的库函数如下:

FILE *fopen( char *file, char *open_mode ); //打开文件,读文件到内存,返回文件信息结构指针
size_t fread(void *ptr, size_t size, size_t n, FILE *stream)//按字节读取文件内容到s中
size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream)//按字节将s地址中的数据写到文件中
char *fgets( char *s, int max_size, FILE * stream); //读一行数据到缓冲区s中
int fputs(const char *str, FILE *stream) ;//将字符串s写入文件
int fscanf(FILE *stream, const char *format, ...) ;//fscanf(文件流指针,格式字符串,输出表列);
int fprintf(FILE *stream, const char *format, ...);//fprintf(文件流指针,格式字符串,输出表列);
int fseek( FILE * stream, long offset, int whence); //移动文件指针到指定位置(0,1,2):SEEK_SET,SEEK_CUR,SEEK_END
void rewind(FILE * stream); //回到文件头
long ftell(FILE * stream); //得到当前文件偏移位置
int feof(FILE *stream);//文件是否结束
fclose(FILE * stream); //关闭文件,刷新缓存到物理磁盘上

针对上述函数,更为详细的描述请大家参考cppreference上的文档描述:https://en.cppreference.com/w/c/io/

常用函数

fopen

用于打开一个文件,用于后续读写。该函数原型如下:

FILE *fopen( const char *filename, const char *mode );            // C99标准
errno_t fopen_s( FILE *restrict *restrict streamptr, const char *restrict filename, const char *restrict mode ); // C11标准

需要注意的是:

  • 该函数返回的是一个FILE结构的指针,如果文件打开失败,则该指针返回值为空
  • 第一个参数filename为文件名,有相对路径和绝对路径两种传入方式
    • 绝对路径:包含完整的路径,如E:\SRC\FileIO\fgets_fputs\mystr.txt

在这里插入图片描述

  • 相对路径:以当前exe所在路径为参考的文件路径,如果需要返回上级目录,使用.. 。比如当前exe位于E:\src\Cheese\Debug 目录下,而待读取的hello.txt位于E:\src\Cheese\Cheese\hello.txt ,则使用相对路径为:..\Cheese\hello.txt
    在这里插入图片描述
  • 如果直接运行exe,则“当前路径”是以exe所在路径为基准的,如果fopen时直接输入文件名,则意味着对应要打开的文件和exe处于同级目录下。
  • 如果通过VS运行exe,则“当前路径”以源码所在的工程路径为基准的,如果fopen时直接输入文件名,则意味着对应要打开的文件位于对应的VS工程目录下。
  • 如果路径使用\ 来标识,需要进行转义:\\
  • 第二个参数是打开文件时使用的模式,主要有以下六种:
File access
mode string
含义 解释 文件存在时的操作 文件不存在时的操作
"r" read 打开文件供读取 从文件头部开始读取 打开失败
"w" write 创建文件供写入 清空文件原有内容,重新写入 创建新文件
"a" append 向文件尾部追加新内容 向文件尾部追加 创建新文件
"r+" read extended 打开文件供读取和写入 从文件头部开始读取 打开失败
"w+" write extended 创建文件供读取和写入 清空文件原有内容,重新写入 创建新文件
"a+" read extended 打开文件供读取和写入 向文件尾部追加 创建新文件
  • 需要注意的是"a"及"a+"模式下,当文件已存在的情况下,是向文件尾部追加内容,这一点与"w"和"w+"不同。这也是课堂练习题不选第二选项的原因。
  • 在一些Windows下C语言的资料中,会提到另一个名为"b"或"t"的后缀,这是所谓的二进制和文本模式。
    • 在POSIX标准中(适用于Unix、Linux等环境),文本和二进制模式本身没有差异
    • 在Windows环境下,由于所采用的换行符是CRLF(16进制的0x0D 0x0A),出于兼容性考虑,在读写过程中会进行与标准换行符(0x0A)的自动转换。具体说来,在文本模式下,对文件写入时,如果遇到0x0D 0x0A,在写入文件时会被转换成0x0A;而在文件读取时,如果只遇到0x0A,会将其转为0x0D 0x0A。另外,Windows下对于文本模式的文件结尾也有特殊规定,具体可参见MSDN中的论述:https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen

In addition to the earlier values, the following characters can be appended to mode to specify the translation mode for newline characters.

In text mode, CTRL+Z is interpreted as an EOF character on input. In files that are opened for reading/writing by using “a+”, fopen checks for a CTRL+Z at the end of the file and removes it, if it’s possible. It’s removed because using fseek and ftell to move within a file that ends with CTRL+Z may cause fseek to behave incorrectly near the end of the file.

In text mode, carriage return-line feed (CRLF) combinations are translated into single line feed (LF) characters on input, and LF characters are translated to CRLF combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb function).

  • fopen函数返回为FILE对象的指针,如果文件打开失败,则该指针为空指针。因此,严谨的写法应该在函数返回后,对指针值进行判断。

fclose

fclose应与fopen配对使用,关闭一个被fopen打开的文件对象指针。其函数原型如下:

int fclose( FILE *stream );

需要注意的是,如果对文件内容进行了写入或修改,只有当调用fclose之后,才能保证对应的修改一定被同步到了对应文件中。

fgets和fputs

概述

这一组函数用于对字符串的读取和写入。函数原型如下:

int fputs( const char *str, FILE *stream );
char* fgets( char *str, int count, FILE *stream );
  • str参数是待写入文件或从文件读出的字符串
  • stream是用于传入fopen打开的FILE*指针,指定读写的文件对象。
  • fgets中的count用于指定最大可从文件读到内存中的字符串长度(通常被设置为str的最大长度)

文本模式

我们先来看一个简单的例子:

FILE* fp = fopen("mystr.txt"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值