fgets does not fill the array completely

試著忘記壹切 提交于 2019-12-11 07:44:38

问题


I want to read a text file and store it into an array data[512].

Here is the code:

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));
    ...    
}

Why does strlen(data) each time return a different value? Why is data in not fully filled?

EDIT

When using fread() inside a while loop:

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));

the data size (last line) is not correct!

Sample Textfile (it is ok for all except the first one where strlen returns 513 instead of 512):

e Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un peintre anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.e Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un peintre anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.e Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un peintre anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.e Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un peintre anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker. Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un peintre anonyme assembla ensemble des morceaux de texte pour réaliser un livre spécimen de polices de texte. Il n'a pas fait que survivre cinq siècles, mais s'est aussi adapté à la bureautique informatique, sans que son contenu n'en soit modifié. Il a été popularisé dans les années 1960 grâce à la vente de feuilles Letraset contenant des passages du Lorem Ipsum, et, plus récemment, par son inclusion dans des applications de mise en page de texte, comme Aldus PageMaker.e Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte standard de l'imprimerie depuis les années 1500, quand un peintre anonyme assembla ensemble des morceaux


回答1:


What does fgets do:

The C library function char *fgets(char *str, int n, FILE *stream) reads a line from the specified stream and stores it into the string pointed to by str. It stops when either (n-1) characters are read, the newline character is read, or the end-of-file is reached, whichever comes first.

So in your code:

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

Will read at most 511 chars, but it'll stop reading once a new line or an EOF is encountered.
If you want to read as many chars as the data array is big, then either read them one by one, using fgetc, or call fgets in a loop, each time appending the rest of the read data to the end of data. An untested example:

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:


fgets() will read until it reaches a newline or the end of file. If your file must have lines separated by newlines of various lengths.

Use fread() instead, it will read as must as you tell it to, unless it hits an end of file.




回答3:


You have to decide if this is a text file or a binary file that you are reading. If it is a textfile fgets and strlen are the right ones, your are reading line by line, and so the length of what is read will differ.

If this is a binary file use fread, but then never do strlen on the buffer. By coincidence your buffer may have 0 bytes, so these would be interpreted as end-of-string character by strlen.



来源:https://stackoverflow.com/questions/26653094/fgets-does-not-fill-the-array-completely

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!