Проблемы с fgets () для цикла for в C - PullRequest
0 голосов
/ 29 мая 2019

Почему я получаю следующий вывод, когда fgets находится за пределами цикла:

Джим, инженер

Джим, инженер

Джим, инженер

Джим, инженер

и следующий вывод, когда fgets находится внутри цикла for:

Джим, инженер

Пэм, медсестра

Шрам, нарушитель спокойствия

Джон, Смит

int main()
{
    int i;
    char line[255];
    FILE *fpointer = fopen("employees.txt", "r");

    for (i=0; i < 4; i++){
        fgets(line, 255, fpointer);
        printf("%s", line);
    }
    fclose(fpointer);

    return 0
}

в fget (), "i" не передается в качестве аргумента, так как же он продолжает перебирать каждую строку в файле .txt?

Ответы [ 2 ]

1 голос
/ 29 мая 2019

fgets прочитает файл, используя fpointer (думает об этом как курсор), и увеличит его. Поэтому каждый раз, когда вы используете fgets, вы перемещаетесь в файле вперед.

0 голосов
/ 29 мая 2019

Хотя у вас уже есть точный ответ, объясняющий движение индикатора положения файла с потоком файлов при каждом вызове fgets() (или любой другой функции ввода), необходима еще одна дополнительная необходимостьточка, которую нельзя упускать, это Всегда проверяйте возврат функции ввода, чтобы убедиться, что вызов завершился до с использованием прочитанной информации.

В вашем случае, при использовании цикла for, если в файле менее 4 строк или если произошла ошибка потока, вы слепо передаете line в printf для вывода, даже не зная, содержит ли ондействительные данные.Это приглашение для неопределенного поведения .Всегда проверяйте возврат.

При чтении данных вы обычно хотите управлять входным циклом с помощью самой функции чтения.В других случаях, например, при запросе конкретного пользовательского ввода, вы хотите постоянно выполнять цикл, пока не будет предоставлена ​​необходимая информация.В обоих случаях вы проверяете и используете возврат функции ввода, чтобы определить, продолжается ли цикл.

Чтобы прочитать все строки в файле, предполагая, что это был ваш ввод, вы просто должны сделать:

#include <stdio.h>
#include <string.h>

int main()
{
    char line[255];
    FILE *fpointer = fopen("employees.txt", "r");

    while (fgets(line, 255, fpointer)) {    /* control read loop with fgets */
        line[strcspn (line, "\r\n")] = 0;   /* trim \n from end of line */
        puts (line);
    }
    fclose(fpointer);

    return 0;
}

Если вы хотите прочитать определенное количество строк, просто включите счетчик, например, чтобы прочитать 4 строки:

int main()
{
    size_t n = 0;
    char line[255];
    FILE *fpointer = fopen("employees.txt", "r");

    /* control read loop with counter and fgets */
    while (n < 4 && fgets(line, 255, fpointer)) {
        line[strcspn (line, "\r\n")] = 0;   /* trim \n from end of line */
        puts (line);
        n++;
    }
    fclose(fpointer);

    return 0;
}

Таким образом, вы включили возврат fgets() иваш счетчик строк в цикле условно.

( примечание: использование strcspn, которое возвращает количество символов в строке, НЕ являющейся частью набора исключений "\r\n",обеспечивает длину строки, исключая конец строки, позволяя вам просто перезаписать первый символ конца строки с помощью '\0' или его числового эквивалента 0. По сути, это делает следующее:)

        size_t len = strlen (line);
        if (len && len - 1 == '\n')
            line[--len] = 0;        /* trim \n from end of line */ 

Дайте мне знать, если у вас есть дополнительные вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...