fgets没有完全填充数组

时间:2014-10-30 12:32:39

标签: c fgets

我想读取一个文本文件并将其存储到数组data[512]

以下是代码:

char filename = "send.txt";

//Open File
FILE *in_file = fopen("send.txt", "r");

if(in_file == NULL){
    printf("Error : couldn't oepn file");
}

char data[512];
while(fgets(data, sizeof(data), in_file) != NULL){
    printf("read size: %d \n", strlen(data));
    ...    
}

为什么strlen(data)每次返回不同的值?为什么data没有完全填满?

修改

在while循环中使用fread()时:

printf("Start Reading \n" );
memset(&data[0], 0, sizeof(data));
size_t numRead = fread(data,1,sizeof(data),in_file);
printf("numRead: %d \n", numRead );
if(numRead == NULL)
{
    printf(" fread() failed\n");
    return 1;
}              
printf("data size: %d \n", strlen(data));

数据大小(最后一行)不正确!

示例文本文件(除了第strlen返回513而不是512之外的所有文件都可以。)

e Lorem Ipsum est simplement du fauxtexteissusédansla composition et la mise en page avant impression。 Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis lesannées1500,quand un peintre anonyme assembla ensemble des morceaux de textepourréaliserunlivrespécimendepolices de texte。 Il n'a pas fait que survivrecinqsiècles,mais s'estaussicoitéàlabureautique informatique,sans que son contenu n'ensoitmodiifié。 Ilaétépopularisédanslesannées1960grâceàravente de feuilles Letraset contenant des passageages du Lorem Ipsum,et,plusrécemment,par son inclusion dans des applications de mise en page de texte,comme Aldus PageMaker.e Lorem Ipsum est simplement du fauxtextecommpusédansla composition et la mise en page avant impression。 Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis lesannées1500,quand un peintre anonyme assembla ensemble des morceaux de textepourréaliserunlivrespécimendepolices de texte。 Il n'a pas fait que survivrecinqsiècles,mais s'estaussicoitéàlabureautique informatique,sans que son contenu n'ensoitmodiifié。 Ilaétépopularisédanslesannées1960grâceàravente de feuilles Letraset contenant des passageages du Lorem Ipsum,et,plusrécemment,par son inclusion dans des applications de mise en page de texte,comme Aldus PageMaker.e Lorem Ipsum est simplement du fauxtextecommpusédansla composition et la mise en page avant impression。 Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis lesannées1500,quand un peintre anonyme assembla ensemble des morceaux de textepourréaliserunlivrespécimendepolices de texte。 Il n'a pas fait que survivrecinqsiècles,mais s'estaussicoitéàlabureautique informatique,sans que son contenu n'ensoitmodiifié。 Ilaétépopularisédanslesannées1960grâceàravente de feuilles Letraset contenant des passageages du Lorem Ipsum,et,plusrécemment,par son inclusion dans des applications de mise en page de texte,comme Aldus PageMaker.e Lorem Ipsum est simplement du fauxtextecommpusédansla composition et la mise en page avant impression。 Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis lesannées1500,quand un peintre anonyme assembla ensemble des morceaux de textepourréaliserunlivrespécimendepolices de texte。 Il n'a pas fait que survivrecinqsiècles,mais s'estaussicoitéàlabureautique informatique,sans que son contenu n'ensoitmodiifié。 Ilaétépopularisédanslesannées1960grâceàravente de feuilles Letraset contenant des passageages du Lorem Ipsum,et,plusrécemment,par son inclusion dans des applications de mise en page de texte,comme Aldus PageMaker。 Le Lorem Ipsum est simplement du fauxtexteocloyédansla composition et la mise en page avant impression。 Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis lesannées1500,quand un peintre anonyme assembla ensemble des morceaux de textepourréaliserunlivrespécimendepolices de texte。 Il n'a pas fait que survivrecinqsiècles,mais s'estaussicoitéàlabureautique informatique,sans que son contenu n'ensoitmodiifié。 Ilaétépopularisédanslesannées1960grâceàravente de feuilles Letraset contenant des passageages du Lorem Ipsum,et,plusrécemment,par son inclusion dans des applications de mise en page de texte,comme Aldus PageMaker.e Lorem Ipsum est simplement du fauxtextecommpusédansla composition et la mise en page avant impression。 Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis lesannées1500,quand un peintre anonyme assembla ensemble des morceaux

3 个答案:

答案 0 :(得分:3)

fgets()将一直读到它到达换行符或文件结尾。如果您的文件必须用不同长度的换行符分隔行。

使用fread()代替它,它将按照您的要求阅读,除非它到达文件末尾。

答案 1 :(得分:3)

fgets做了什么:

  

C库函数char * fgets(char * str,int n,FILE * stream)从指定的流中读取一行并将其存储到str指向的字符串中。当读取(n-1)个字符,读取换行符或达到文件结尾时(以先到者为准),它会停止。

所以在你的代码中:

fgets(data, sizeof(data), in_file);

最多会读取 511个字符,但一旦遇到新行或EOF,它就会停止阅读。
如果你想要读取data数组很大的字符数,那么要么使用fgetc逐个读取它们,要么在循环中调用fgets,每次附加其余字符读取数据到data的末尾。 未经测试的示例:

size_t data_len = 0,
    total_len = 0,
    max_len = sizeof data/sizeof *data;//sizeof *data is one, unless you decide to use w_char or something
while ((fgets(data + data_len, max_len - data_len, in_file)) != NULL)
{
    data_len = strlen(data);
    if (data_len >= 511)//==511 should work, but you never know
    {
        total_len += data_len;//keep running total
        data_len = 0;
        printf("%s\n", data);
        data[0] = '\0';//make empty string
    }
}
if (data_len)
    printf("%s\nread size: %zu\n", data, total_len + data_len);

答案 2 :(得分:1)

您必须确定这是您正在阅读的文本文件还是二进制文件。如果是文本文件fgetsstrlen是正确的文件,那么您正在逐行阅读,因此读取的内容的长度会有所不同。

如果这是二进制文件,请使用fread,但永远不要在缓冲区上执行strlen。巧合的是,您的缓冲区可能有0个字节,因此这些字符串将被strlen解释为字符串结尾字符。