Формат для чтения строки символов, отличной от новой строки, %[^\n]
, с необязательным, но очень рекомендуемым префиксом ширины для максимального количества символов, которое нужно сохранить в массиве назначения. Трейлинг *%s
не имеет смысла.
Обратите внимание, что этот scanf
спецификатор преобразования будет принимать номера меток как часть имени:
scanf
должен прекратить читать имя, когда оно находит цифру. Это позволит пользователю вводить данные по одной строке для каждого учащегося, что он / она может сделать в любом случае, если появится подсказка.
Формат для этого %[^0-9\n]
, и для предотвращения неопределенного поведения, если пользователь вводит более 49 символов для имени, укажите этот предел с помощью %49[^0-9\n]
.
Использование scanf()
для анализа ввода по-прежнему хрупко: восстановление после неверного ввода утомительно.
Вот исправленная версия:
#include <stdio.h>
struct student {
int r;
char a[50];
int c1, c2, c3;
float total, per;
} s[100];
int main() {
int i, n;
printf("Enter total number of students\n");
if (scanf("%d", &n) != 1 || n > 100)
return 1;
for (i = 0; i < n;) {
printf("Enter details of student\nRollNo Name c1 c1 c3 marks\n");
if (scanf("%d %49[^0-9\n] %d %d %d",
&s[i].r, s[i].a, &s[i].c1, &s[i].c2, &s[i].c3) == 5) {
i++;
} else {
int c;
fprintf(stderr, "input error\n");
/* consume the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
if (c == EOF) {
fprintf(stderr, "unexpected end of file\n");
return 1;
}
}
}
for (i = 0; i < n; i++) {
printf("%d %s %d %d %d\n", s[i].r, s[i].a, s[i].c1, s[i].c2, s[i].c3);
}
return 0;
}