C 读到新行

C 读到新行,c,file-io,C,File Io,嗨 我的程序读取CSV文件。 所以我用fgets一次读一行。 但是现在接口规范说可以在少数列中找到空字符。 所以我需要用另一个函数替换fgets来读取文件 有什么建议吗?使用fread,然后扫描块中的分隔符 检查功能int T_fread(文件*输入)at使用fread,然后扫描块以查找分隔符 检查位于的函数int T_fread(FILE*input)如果文本流具有NUL(ascii 0)字符,则需要将文件作为二进制文件处理,并使用fread读取文件。这有两种方法 将整个文件读入内存。文件的长

嗨 我的程序读取CSV文件。 所以我用fgets一次读一行。 但是现在接口规范说可以在少数列中找到空字符。 所以我需要用另一个函数替换fgets来读取文件
有什么建议吗?

使用fread,然后扫描块中的分隔符


检查功能
int T_fread(文件*输入)
at

使用fread,然后扫描块以查找分隔符


检查位于

的函数
int T_fread(FILE*input)
如果文本流具有
NUL
(ascii 0)字符,则需要将文件作为二进制文件处理,并使用
fread
读取文件。这有两种方法

  • 将整个文件读入内存。文件的长度可以通过
    fseek(fp,0,SEEK\u END)
    获得,然后调用
    ftell
    。然后可以为整个文件分配足够的内存。一旦进入内存,解析文件应该相对容易。这种方法只适用于较小的文件(最大可能小于50M)。有关奖励分数,请查看
    mmap
    功能

  • 逐字节读取文件并将字符添加到缓冲区,直到找到换行符

  • 逐位读取和解析。创建一个比最大行大的缓冲区,并用文件中的内容填充它。然后,解析并提取尽可能多的行。将剩余部分添加到新缓冲区的开头,然后读取下一位。使用更大的缓冲区将有助于最大限度地减少复制


  • 如果文本流具有
    NUL
    (ascii 0)字符,则需要将文件作为二进制文件处理,并使用
    fread
    读取文件。这有两种方法

  • 将整个文件读入内存。文件的长度可以通过
    fseek(fp,0,SEEK\u END)
    获得,然后调用
    ftell
    。然后可以为整个文件分配足够的内存。一旦进入内存,解析文件应该相对容易。这种方法只适用于较小的文件(最大可能小于50M)。有关奖励分数,请查看
    mmap
    功能

  • 逐字节读取文件并将字符添加到缓冲区,直到找到换行符

  • 逐位读取和解析。创建一个比最大行大的缓冲区,并用文件中的内容填充它。然后,解析并提取尽可能多的行。将剩余部分添加到新缓冲区的开头,然后读取下一位。使用更大的缓冲区将有助于最大限度地减少复制


  • fgets
    可以很好地处理嵌入的空字节。用
    \n
    (使用
    memset
    )预先填充缓冲区,然后使用
    memchr(buf,'\n',sizeof buf)
    。如果
    memchr
    返回
    NULL
    ,则缓冲区太小,需要放大它才能读取行的其余部分。否则,您可以通过检查下一个字节来确定找到的换行符是行尾还是预填充缓冲区的填充。如果您找到的换行符位于缓冲区的末尾或紧跟在它后面有另一个换行符,则它来自填充,前一个字节是由
    fgets
    插入的空终止符(不是文件中的空)。否则,您找到的换行符后面有一个空字节(由
    fgets
    插入的终止符),它是换行符的结尾


    其他方法会很慢(重复
    fgetc
    )或浪费(并有耗尽资源的风险)(将整个文件加载到内存中)。

    fgets
    对嵌入的空字节非常有效。使用
    \n
    (使用
    memset
    )预填充缓冲区,然后使用
    memchr(buf,'\n',sizeof buf)
    。如果
    memchr
    返回
    NULL
    ,则缓冲区太小,您需要放大它以读取行的其余部分。否则,您可以通过检查下一个字节来确定找到的换行符是行尾还是预填充缓冲区的填充符。如果找到的换行符位于缓冲区的末尾er or后面有另一个换行符,它来自填充,前一个字节是由
    fgets
    插入的空终止符(不是文件中的空)。否则,您找到的换行符后面有一个空字节(由
    fgets
    插入的终止符),它是换行符的结尾


    其他方法会很慢(重复
    fgetc
    )或浪费(并可能耗尽)资源(将整个文件加载到内存中)。

    但我不知道每行的最大大小。如何确定长度。以及如何将文件指针重置到正确的点。以下是步骤(I)打开文件(ii)获取文件的大小,比如说它是n字节(iii)分配一个缓冲区,比如说m字节(m.LE.n)(iv)位置到打开文件的开始位置(iv)执行fread(将文件的m字节放入缓冲区),直到整个文件被读取(v)通过缓冲区来检测分隔符和NULL。作为一种优化,我建议您考虑用另一个字符(如空格或换行符或适当的字符)替换NULL——然后您可以继续使用标准的字符串库函数,但我不知道每行的最大大小。lso我将如何将文件指针重置到正确的点。以下是步骤(I)打开文件(ii)获取文件大小(假设为n字节)(iii)分配缓冲区(假设为m字节)(m.LE.n)(iv)位置到打开文件的开始位置(iv)执行fread(将文件的m字节放入缓冲区),直到整个文件被读取(v)通过缓冲区来检测分隔符和NULL。作为优化,我建议您考虑用另一个字符(如空格或换行符或适当的字符)替换NULL,然后继续使用标准的字符串库函数。