Один из способов реализации этой цели будет включать использование fgets()
вместо scanf()
читать в строке ввода в то время. Затем можно использовать strtok()
, чтобы разбить линию ввода на токены, а strtol()
можно использовать для анализа токенов на номера. По сравнению с scanf()
, гораздо проще использовать fgets
для обработки неструктурированного пользовательского ввода.
Приведенный ниже код делает это. Если в строке ввода слишком много элементов, слишком мало элементов или если один из элементов не является допустимым числом, выводится сообщение, и строка должна быть введена снова.
Поскольку каждая строка вводится пользователем, strtok()
используется, чтобы разбить линию на жетоны. Список разделителей токенов хранится в delims[]
. Обратите внимание, что маркеры могут быть разделены пробелами или вкладками; сами разделители не являются частью токена, поэтому включение \r
и \n
гарантирует, что эти символы не будут частью финального токена в строке.
Когда токен найден, strtol()
используется, чтобы по возможности преобразовать его в целое число. После вызова strtol()
указатель tail
указывает на первый символ в токене, который не был частью числа; если tail
указывает на терминатор NUL
, тогда вся строка анализировалась как число, иначе вход считается неудачным, и строка должна быть введена снова.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUF_SIZE 1000
int main(void)
{
size_t r = 3;
size_t c = 5;
size_t i, j;
char buffer[BUF_SIZE];
char *token;
char *tail;
const char delims[] = " \t\r\n";
int arr[r][c];
int temp_val;
printf("Enter rows of %zu data elements:\n", c);
for(i = 0; i < r; i++){
j = 0;
if (fgets(buffer, BUF_SIZE, stdin) == NULL) {
perror("Error in fgets()");
exit(EXIT_FAILURE);
}
token = strtok(buffer, delims);
while (token != NULL) {
temp_val = strtol(token, &tail, 10);
if (*tail == '\0') {
arr[i][j] = temp_val;
++j;
} else { // token not a valid number
j = 0;
break;
}
if (j > c) { // too many input values
break;
}
token = strtok(NULL, delims);
}
if (j != c) {
printf("insufficient datapoints\n");
--i; // enter row again
}
}
for (i = 0; i < r; i++) {
for (j = 0; j < c; j++) {
printf("%5d", arr[i][j]);
}
putchar('\n');
}
return 0;
}
Пример взаимодействия:
Enter rows of 5 data elements:
1 2 3 4
insufficient datapoints
1 2 3 4 5 6
insufficient datapoints
1 x 2 3 4
insufficient datapoints
1 2 3 4 x
insufficient datapoints
1 2 3 4 5 x
insufficient datapoints
1 2x 3 4 5
insufficient datapoints
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
если 'зсапЕ()' не возвращают 'EOF' труба не близко. – Stargateur
@ccpgh как бы я это сделал? –
Использовать 'fgets' и' strtok'? – BLUEPIXY