您好 我的程序读取CSV文件。 所以我用fgets一次读一行。 但是现在接口规范说可以在很少的列中找到NULL字符。 所以我需要用另一个函数替换fgets来从文件中读取 有什么建议吗?
答案 0 :(得分:3)
如果您的文本流有NUL
(ascii 0)字符,则需要将文件作为二进制文件处理,并使用fread
来读取文件。有两种方法。
将整个文件读入内存。文件的长度可以通过fseek(fp, 0, SEEK_END)
获得然后调用ftell
。然后你可以为整个文件分配足够的内存。一旦在内存中,解析文件应该相对容易。这种方法只适用于小文件(最大可能小于50M)。对于奖励标记,请查看mmap
功能。
逐字节读取文件并将字符添加到缓冲区,直到找到换行符。
逐位读取和解析。创建一个比最大行最大的缓冲区,并用文件中的内容填充它。然后,您可以解析并提取尽可能多的行。将余数添加到新缓冲区的开头,然后读取下一位。使用更大的缓冲区将有助于最大限度地减少复制。
答案 1 :(得分:1)
答案 2 :(得分:1)
fgets
与嵌入的空字节完美配合。使用\n
预先填充缓冲区(使用memset
),然后使用memchr(buf, '\n', sizeof buf)
。如果memchr
返回NULL
,则您的缓冲区太小,您需要将其放大以阅读该行的其余部分。否则,您可以通过检查下一个字节来确定您找到的换行符是行的结尾还是预先填充缓冲区的填充。如果您找到的换行位于缓冲区的末尾或者在其后面有另一个换行符,则它来自填充,而前一个字节是由fgets
插入的空终止符(不是文件中的空值)。否则,您找到的换行符后面会有一个空字节(由fgets
插入的终结符,并且它是行尾换行符。
其他方法将很慢(重复fgetc
)或浪费(并且风险耗尽)资源(将整个文件加载到内存中)。