проблема с выходом из цикла fgets - PullRequest
0 голосов
/ 12 января 2019

Я сделал простую C-программу, включающую цикл for и fgets для получения имени из пользовательского ввода. Но проблема в том, что когда пользователь вводит номер сотрудника, его экранируют от имени. Я не уверен, в чем проблема.

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


int main (){

        int emp;
        int i;
        char name[60];
        int id;


        printf("Please enter the number of employee :");
        scanf("%d", &emp);

        for (i=1; i<emp; i++){
                    printf(" Employee %d : \n",i++);
                    printf("Enter an employee name:");
                    fgets(name, 60, stdin);
                    printf("\nID:");
                    scanf("%d", &id);

                    printf(" ------------------------------------- ");


        }



}

Ответы [ 3 ]

0 голосов
/ 12 января 2019

Это ошибка пользователя. Не нажимайте ввод после количества сотрудников. Не нажимайте ввод после идентификатора, если это не последний сотрудник. Код ожидает чтения следующего ввода сразу после каждого числового ввода, так что это то, что пользователь должен предоставить.

Например, скажем, у вас два сотрудника, Джефф - сотрудник 1, а Эрик - сотрудник 2. Вы должны ввести «2Jeff», а затем «1Eric». Поскольку код не ожидает, что ввод будет строкой, пользователь не должен вводить строку в ответ.

Например:

Пожалуйста, введите количество сотрудников: 2Jeff
Сотрудник 1:
Введите имя сотрудника:
ID: 1Eric


Пользовательские данные выделены жирным шрифтом. Программное обеспечение вело себя точно так, как ожидалось.

Однако, чтобы обеспечить лучшее руководство для пользователя, было бы более полезно сообщить пользователю об этом. Например, «Пожалуйста, введите номер сотрудника:» заставляет пользователя думать, что он должен ответить строкой. Поэтому в коде должно быть написано что-то вроде: «Пожалуйста, введите номер сотрудника, за которым следует имя первого сотрудника без пробела между ними». Аналогичным образом, «ID:» следует изменить на «ID», за которым следует имя следующего сотрудника (если есть) без пробелов между ними ».

Таким образом, пользователь знает, чего ожидает код.

0 голосов
/ 12 января 2019

fgets() читает Введите , осталось '\n', от предыдущего scanf("%d", &emp); @ xing .

"%d" читает только до последней цифры, она не использует символы после последней цифры. Эти символы, такие как '\n', остаются в stdin для следующей операции ввода, которая оказалась fgets(). Поэтому fgets() затем читает этот одиночный '\n' как короткую строку.

Затем попытается прочитать следующее имя с помощью scanf("%d", &id);.

Смешивать scanf() с fgets().

беспорядок

Вместо этого используйте scanf() и используйте fgets() для всего пользовательского ввода.

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

int main (void) {
  int emp;
  int i;
  char ibuffer[42];
  char name[60];
  int id;

  printf("Please enter the number of employee :");
  fgets(ibuffer, sizeof ibuffer, stdin);
  emp = atoi(ibuffer); 
  // For better error detection, check fgets return value and use strtol()

  for (i=1; i<emp; i++) {
    printf(" Employee %d : \n",i++);

    printf("Enter an employee name:");
    fgets(name, sizeof name, stdin);
    name[strcspn(name, "\n")] = '\0'; // lop off potential \n

    printf("\nID:");
    fgets(ibuffer, sizeof ibuffer, stdin);
    id = atoi(ibuffer); 

    printf(" ------------------------------------- ");
    printf("\nID:%3d  employee name:<%s>\n", id, name);
  }
}
0 голосов
/ 12 января 2019

Это происходит потому, что вы смешиваете fgets и scanf вызовы.

Спецификатор формата %d для scanf читает цифры. Все после этих цифр, , включая перевод строки , остается во входном буфере. Затем, когда вызывается fgets, он читает все до следующего символа новой строки. Следующим символом в буфере является символ новой строки, поэтому он сразу читает это.

Заменить вызов fgets на scanf, чтобы он соответствовал остальным входным данным:

scanf("%59s", name);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...