Получение строки пользовательского ввода в справке C.

#c

#c

Вопрос:

Я прошелся по всему Интернету и перепробовал кучу разных вещей, но, похоже, они никогда не работали. Каждый раз, когда я запускаю программу, она пропускает возможность ввести что-либо для имени студента и отправляется прямо в отдел. Кроме того, мы новички в C, и нам действительно сказали использовать printf и scanf, но когда пользователь вводит имя, например, joe shmo, это делает некоторые странные вещи.

 fputs("Please enter the students name: ", stdout);
fflush(stdout);
fgets(studentArray[empty].name, sizeof studentArray[empty].name, stdin);

printf("nPlease enter the students department: ");
scanf("%s", studentArray[empty].department);
printf("nPlease enter the students rank: ");
scanf("%d", amp;studentArray[empty].rank);
  

РЕДАКТИРОВАТЬ: Странная штука, например, если я введу два имени, то есть Джо шмо, оно примет joe в качестве имени и автоматически добавит shmo в отдел. studentArray — это массив созданной мной структуры…

 typedef struct {
char name[MAX_NAME_LENGTH];
char department[MAX_DEPT_LENGTH];
int rank;
} student;
  

Комментарии:

1. Пожалуйста, определите «странные вещи». Также, пожалуйста, предоставьте определение studentArray .

2. Есть ли какой-либо код перед этим, который вы не показываете?

3. Старайтесь не смешивать scanf() и fgets() — prefer fgets() , за которыми следует синтаксический анализ входных данных.

Ответ №1:

Когда программа достигает fgets() бьюсь об заклад, что во входном буфере есть ожидающий 'n' из предыдущего scanf() . Я предлагаю вам избавиться от этого 'n' и любого предыдущего ввода.

Например, с

 int getridofextrainput(void) {
  int ch;
  while (((ch = getchar()) != 'n') amp;amp; (ch != EOF)) /* void */;
  return ch;
}
  

Затем используйте эту функцию в своем коде там, где вы считаете это необходимым (до fgets ).

Комментарии:

1. Возможно, захочется добавить ungetc к этой функции

2. @anatolyg: почему? ???!?! В принципе, я хочу избавиться от последнего 'n' в буфере символа, который является последним прочитанным символом. Зачем мне возвращать символ, который я не хочу?

Ответ №2:

Это то, что происходит, когда вы смешиваете fscanf и fgets .

Когда fscanf считывается число, оно останавливается прямо в конце этого числа, перед следующим символом новой строки. Когда после этого fgets считывается строка, она останавливается на следующем символе новой строки, который, к сожалению, сразу следует.

Если бы вы использовали только fscanf для чтения всех данных, у вас не возникло бы проблем. Это нетривиально, потому что некоторые из ваших имен содержат пробелы. Можно прочитать имя, содержащее пробел, используя fscanf вот так:

 scanf("%[^n]", studentArray[empty].department);
  

Если бы вы использовали только fgets для чтения всех данных, у вас тоже все было бы в порядке. К сожалению, это тоже не тривиально: для чтения чисел требуется временный буфер.

 char temp[42];
fgets(temp, sizeof temp, stdin);
sscanf(temp, "%d", amp;studentArray[empty].rank);