Хотя лучшим способом выполнить чтение неизвестного числа целых чисел из строки было бы чтение всей строки в буфер достаточного размера, а затем пошаговое перемещение по буферу с помощью strtol
(для обновления используется параметр endptr
ваша позиция в буфере на 1-character
после последнего преобразованного значения), вы можете использовать scanf
и выполнить то же самое.
Один из способов использования scanf
для чтения нескольких целых чисел из строки ввода - просто прочитать каждый символ и подтвердить, что это не символ '\n'
или EOF
. Если персонаж не цифра (или знак '-'
, предшествующий цифре - благодаря Аджаю Брахмакшатрии ), тогда просто перейдите и получите следующий символ. Если символ представляет собой цифру, поместите его обратно в stdin
с помощью ungetc
, а затем вызовите scanf
и , чтобы подтвердить преобразование , прежде чем обновлять среднее значение для девочек или мальчиков на основе знака ввода.
Вы можете сделать что-то вроде следующего:
int height;
fputs ("enter heights: ", stdout);
while ((height = getchar()) != '\n' && height != EOF) {
/* if not '-' and not digit, go read next char */
if (height != '-' && !isdigit (height))
continue;
ungetc (height, stdin); /* was digit, put it back in stdin */
if (scanf ("%d", &height) == 1) { /* now read with scanf */
if (height > 0) { /* postive val, add to girls */
avg_girls += height;
counter_girls++;
}
else { /* negative val, add to boys */
avg_boys += height;
counter_boys++;
}
}
}
Макрос isspace()
предоставляется заголовком ctype.h
. Если вы не можете включить другие заголовки, просто проверьте, является ли height
цифрой вручную, например,
if (height != '-' && (height < '0' || '9' < height))
continue;
(помните, что вы читаете символов с getchar()
, поэтому проведите сравнение с символами ASCII для '0'
и '9'
)
Другая альтернатива - прочитать всю строку ввода в буфер, а затем повторно вызывать sscanf
, конвертируя целые числа, когда вы работаете через буфер, дополнительно используя спецификатор "%n"
, чтобы сообщить количество символов, использованных при вызове sscanf
. (например, используя "%d%n"
и предоставив указатель на int
для хранения значения, предоставленного "%n"
) Затем вы можете сохранить промежуточную сумму смещения от начала буфера, чтобы добавить к вашему указатель на позицию sscanf
для следующего чтения.
В любом случае все в порядке, но чтение строки за раз представляет для гораздо меньшего количества подводных камней, с которыми приходится работать новому программисту на С, чем попытки работать с scanf
и stdin
.