为什么 c 中的 fread() 会读取额外的“#newlines”字符?

pho*_*nix 5 c file-io fread

当我尝试使用fread()将文件复制到字符串时,我从文件中获取了与新行数完全相同的额外字符。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#define LEN 5000000

int main()
{
   char *in = (char*) malloc(LEN);
   FILE *f=fopen("in.txt","r");
   fread(in,5000000,1,f);
   printf("%ld\n", ftell(f)); 
   in[ftell(f)]=0;
   int l;
   for(l=0;true;l++)
   {
      if(in[l]<10)
        break;
      printf("%d ",in[l]);
   }
   printf("\n");
}
Run Code Online (Sandbox Code Playgroud)

该程序的输入是:

1  
2  
<newline>
Run Code Online (Sandbox Code Playgroud)

输入链接:https://paste.fedoraproject.org/388281/46780193/
对于输出,我正在打印读取的字符的 ASCII 值:

6  
49 10 50 10 13 10  
Run Code Online (Sandbox Code Playgroud)

如果输入是:

1  
2  
3  
<newline>  
Run Code Online (Sandbox Code Playgroud)

输入链接: https: //paste.fedoraproject.org/388280/
然后输出是:

9  
49 10 50 10 51 10 51 13 10  
Run Code Online (Sandbox Code Playgroud)

我看到了其他一些测试用例。在每个测试用例中,额外的字符数始终是新行数。
我有几个问题:
-为什么图案是这样的?
-这与 Windows 中新行占用 2 个字节的事实有何关系?
- 如何去掉那些多余的字符?
我用谷歌搜索了类似的问题,但没有找到答案。请有人解释一下?

250*_*501 4

在以文本模式打开的流上调用 ftell (例如在您的示例中)没有意义1

函数的用法fread不正确,大小和计数参数被切换。这意味着读取始终是部分的,因为您的文件中没有 5000000 个字符。因此,调用后数组中元素的值具有不确定的2 个值。(您的案例中的逻辑元素是大小为 5000000 的单个元素。)

您看到的结果没有意义。读取不确定的值可能会导致未定义的行为。

读取文件的正确方法是将正确的参数传递给 fread 并使用返回值来确定成功读取的字符数:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

int main()
{
    unsigned char in[500] = { 0 } ;
    FILE *f=fopen("in.txt","r");
    assert( f ) ;

    const size_t read = fread(in,1,500,f);
    printf( "read: %zu\n" , read );

    for( size_t index = 0 ; index < read ; index++ )
    {
        printf( "%hhu " , in[index] );
    }

    fclose( f );
}
Run Code Online (Sandbox Code Playgroud)

使用这个正确的程序,当文件具有内容时(点不是文件的一部分):

.
1
2
3

.
Run Code Online (Sandbox Code Playgroud)

将读取并打印正确的值:

read: 7
49 10 50 10 51 10 10
Run Code Online (Sandbox Code Playgroud)

对于每个数字,有一个换行符,由值310表示,并在末尾附加一个换行符。


1(引用自:ISO:IEC 9899:201x 7.21.9.4 ftell 函数 2)
对于文本流,其文件位置指示符包含未指定的信息,fseek 函数可使用该信息将流的文件位置指示符返回到其位置拨打电话的时间;两个此类返回值之间的差异不一定是写入或读取的字符数的有意义的度量。

2(引用自:ISO:IEC 9899:201x 7.21.8.1 fread 函数 2)
如果读取了部分元素,则其值是不确定的。

3在windows文件中,换行符由两个字符表示:13、10。回车和换行。但是,当以文本模式读取文件时,换行符始终只是换行符:10。您看到字符 13 是因为程序的行为没有意义。如果您(正确地)以二进制模式打开并读取文件,您将看到由两个字符表示的换行符。