Skip to content

以字符串方式读文件

李述铜

1013字约3分钟

2024-08-08

提示

同学,你好,欢迎学习本课程!本课程是介绍了FATFS文件系统模块的基本使用,是一门相对较简单的课程。

如果你对文件系统的实现比较感兴趣,也可以关注我的《从0到1写FAT32文件系统》课程。

欢迎转载本文章,转载请注明链接来源,谢谢!

在某些情况下,可能希望逐行读取读取文件内容,即一次读取一行,并将该行的内容存储在指定的缓冲区中。这对于解析配置文件、日志文件等非二进制文件非常有用。

显然,这个功能是f_read()函数无法完成的,f_read()函数只能以二进制的方式读取要求的数据量,并不会在遇到换行符时,立即返回。

主要内容

f_gets函数可用于从文件中读取字符串,具体而言,它会在读取到\n符时立即退出,并且保证读取的字符串以\0结尾。

TCHAR* f_gets (
  TCHAR* buff, /* [OUT] 读取缓冲区 */
  int len,     /* [IN] 读取缓冲区的大小 */
  FIL* fp      /* [IN] 文件对象 */
);

参数:

  • buff:用于存储读取字符串的缓冲区的指针。
  • len:读取缓冲区的大小。
  • fp:打开的文件对象结构的指针。

返回值:

  • 当函数成功时,buff将被返回。当没有字符串可读取或者在读取过程中发生任何错误时,它会返回空指针。具体是何原因,可以通过f_eof和f_error函数进行检查。

注意事项

\r\n和\n

在识别文件中行时,往往会碰到\r\n和\n的问题。

  1. 回车和换行符(\r\n):在Windows的操作系统中,通常使用回车(\r)和换行(\n)两个字符来表示换行。这被称为CRLF行尾标记。即每行的结尾包括\r\n
  2. 换行符(\n):在类似Unix和Linux的操作系统中,通常只使用换行字符(\n)来表示换行。这被称为LF行尾标记,即每行的结尾只包括\n字符。

具体为什么会这样呢?大概是历史遗留和操作系统的不同设计决策,具体我们不需要关心。但是这种不同行结束表示方法,会导致在读取文件时存在一些麻烦。

假设,在存储设备上有一个文件,使用CRLF(\r\n)作为行尾标记,其内容如下:

这是第一行\r\n
这是第二行\r\n
这是第三行\r\n

由于FATFS默认以\n来判断文件是否结束,因此使用f_gets()进行读取时,读取到的文件内容为3行,依次为:

这是第一行\r
这是第二行\r
这是第三行\r

显然,这就导致了每一行多出一个不必要的\r字符。因此,\r在读取时是必须要去掉的。

为了在读取时规避这一问题,可以配置FF_USE_STRFUNC控制读取时,将\r字符自动跳过。

FF_USE_STRFUN值Description
0禁用字符串函数
1不使用LF-CRLF转换
2使用LF-CRLF转换

Unicode编码问题

当FatFs配置为Unicode API(FF_LFN_UNICODE >= 1)时,字符串函数(f_putc、f_puts、f_printf和f_gets)的数据类型也切换为Unicode。通过此函数读取的文件上的字符编码被假定为FF_STRF_ENCODE。如果文件上的字符编码与API上的字符编码不同,它将在此函数中进行转换。在这种情况下,具有错误编码的输入字符将丢失。

需要注意的是,f_gets函数是f_read函数的包装函数,它用于从文件中读取字符串。此函数在FF_USE_STRFUNC大于或等于1时可用。当设置为2时,文件中包含的'\r'将被去除。

f_gets函数常用于从文本文件中逐行读取文本。