C Игнорировать символ новой строки \ n, используя getline - PullRequest
0 голосов
/ 08 октября 2018

Я хочу прочитать переменное количество строк в C, используя функцию

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

.Поэтому я придумал следующий код:

int main() {
    int number;
    char *line;
    size_t len;
    scanf("%d", &number);
    for (int i = 0; i < number; ++i) {
        line = NULL;
        getline(&line, &len, stdin);
        printf("%s", line);
    }
}

Проблема с приведенным выше кодом состоит в том, что первый вызов getline читает символ новой строки ('\n'), который следует за введенным номером вместопервая строкаДобавление одной из следующих строк кода (обозначается OPTION 1 resp. OPTION 2) устраняет проблему:

int main() {
    int number;
    char *line;
    size_t len;
    scanf("%d", &number);
    // fflush(stdin);                                            /* OPTION 1 */
        for (int i = 0; i < number; ++i) {
        line = NULL;
        getline(&line, &len, stdin);
        // while (*line == '\n') getline(&line, &len, stdin);    /* OPTION 2 */
        printf("%s", line);
    }
}

Мои вопросы:

Добавляется одна изэти строки (OPTION 1, OPTION 2) правильный способ сделать это?

Если так, какой из них предпочтительнее другого?

Если нет, какой будет правильный путь?

Ответы [ 2 ]

0 голосов
/ 08 октября 2018

Является ли добавление одной из этих строк (ОПЦИЯ 1, ОПЦИЯ 2) правильным способом сделать это?

ВАРИАНТ 1 - неопределенное поведение в соответствии со стандартом, поэтому я бы не рекомендовалдаже если он работает в вашей системе.

ВАРИАНТ 2 лучше, и он "съест" '\n', оставленный scanf, что вам нужно.Но он также «съест» любой последующий ввод, состоящий только из новой строки.

Если вы просто хотите «съесть» новую строку из ввода number Я, вероятно, сделаю:

int main() {
   int number;
   char *line = NULL;
   size_t len = 0;
   getline(&line, &len, stdin);
   if (sscanf(line, "%d", &number) != 1)
   {
       // Illegal input
       exit(1);
   }
   for (int i = 0; i < number; ++i) {
     // -------------------    line = NULL;   Delete this - see below
     getline(&line, &len, stdin);
     printf("%s", line);
   }
   free(line);
   retur 0;
}

Обратите внимание, что вы должны установить line в NULL только в начале программы.Установка его в NULL в каждом цикле вызывает утечки памяти.Также обратите внимание на free(line)

0 голосов
/ 08 октября 2018

Проблема с scanf.

scanf("%d", &number);

Вы читаете целое число из stdin.Однако, нажав Enter, он автоматически добавляет «\ n» в конце ввода.Поэтому, как только scanf сделано, в stdin остается "\n".

Взгляните на это, что дает более подробную информацию: Удалить \ n после scanf (), который читает целое число

Чтобы избавиться от новой строки после scanf, одним простым решением является добавление "\ n" в конце строки формата:

int main() {
   int number;
   char *line;
   size_t len;
   scanf("%d\n", &number);
   for (int i = 0; i < number; ++i) {
     line = NULL;
     getline(&line, &len, stdin);
     printf("%s", line);
   }
}

, который сканирует дляцелое число, за которым следует необязательный пробел.

...