Вы можете использовать sscanf()
и классы символов для своих целей, но есть небольшие проблемы с вашей строкой формата:
A-Z
предполагает кодировку ASCII или, по крайней мере, кодировку, где буквы являются смежными. - в конце
-
имеет особое значение, поместите da sh в первую позицию, чтобы явно соответствовать da sh. - префикс длины отсутствует, поэтому имя или город, длина которого превышает 49 символов, переполнит целевой массив.
Вместо того, чтобы использовать fgets()
, вы должны прочитать строку вручную, чтобы обнаружить слишком длинные строки.
Вы можете добавить дополнительные %c
чтобы проверить наличие дополнительных символов в конце строки. Сохранение преобразованного значения не требуется, если вы не собираетесь использовать значения поля, но вы должны преобразовать число, чтобы проверить, находится ли его значение в требуемом диапазоне:
char str[150];
char name[50];
char city[50];
char agestr[4];
size_t i;
int c, age, pos, n;
for (i = 0; (c = getchar()) != EOF && c != '\n'; i++) {
if (i < sizeof(str) - 1)
str[i] = (char)c;
}
if (c == EOF && i == 0) {
printf("end of file\n");
return -1;
}
if (i >= sizeof(str)) {
printf("line too long\n");
return 0;
}
str[i] = '\0';
pos = 0;
/* validate the name */
if (sscanf(str + pos, "%49[-a-zA-Z ]%n", name, &n) != 1 || str[pos + n] != ',') {
printf("invalid name\n");
return 0;
}
pos += n + 1;
/* validate the age */
if (str[pos] == '0' || sscanf(str + pos, "%3[0-9]%n", agestr, &n) != 1 || str[pos + n] != ',') {
printf("invalid age\n");
return 0;
}
age = atoi(agestr);
if (age < 18 || age > 120) {
printf("age out of range: %d\n", age);
return 0;
}
pos += n + 1;
/* validate the city */
if (sscanf(str + pos, "%49[-a-zA-Z]%n", city, &n) != 1 || str[pos + n] != '\0') {
printf("invalid city\n");
return 0;
}
/* Input was validated... proceed */