2017-01-26 11 views
1

Я использую ввод пользователя для заполнения массива 2d. Пользователь вводит числа в одной строке, и я затем использовать вложенные циклы, чтобы заполнить массив следующим образом:Проверьте, нет ли трубы stdin в C

//User inputs: "1 2 3 4 5" 

for(i = 0; i < r; i++){ 
    for(j = 0; j < c; j++){ 
      scanf("%d", &arr[i][j]); 
    } 
} 

Однако, проблема в том случае, если пользователь вводит 5 Интс, когда есть место для 6, он просто ждет еще один вход. Как я могу определить, недостаточно ли чисел?

Я попытался с помощью этого, но это не сработало:

for(i = 0; i < r; i++){ 
    for(j = 0; j < c; j++){ 
     if (!feof(stdin)){ 
      scanf("%d", &arr[i][j]); 
     } 
     else{ 
      printf("insufficient datapoints\n"); 
     } 
    } 
} 
+0

если 'зсапЕ()' не возвращают 'EOF' труба не близко. – Stargateur

+0

@ccpgh как бы я это сделал? –

+0

Использовать 'fgets' и' strtok'? – BLUEPIXY

ответ

1

Один из способов реализации этой цели будет включать использование 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 
1

Вы можете использовать быстрый взгляд вперед в потоке и тестовых символов, прежде чем вы на самом деле потребляют их. (Хорошо, что в с).

Вы можете использовать это, чтобы игнорировать пробелы (вам нужно будет это сделать).

Вы также можете использовать это загляденное значение, чтобы указать, были ли введены недостаточные символы.

Заглядывание должно быть выполнено ДО ТОГО, ЧТОБЫ ПРОЧИТАТЬ (scanf).

Добавлен грубый пример кода ниже

#include <stdio.h> 
#include <ctype.h> 

int r=3; 
int c=2; 

int arr[100][100]; // FIX magic 

int main(int argc, char** argv[]) { 

    for(int i=0; i<r; i++) { 
    for(int j=0; j<c; j++) { 

     if (feof(stdin)) { 
     // error check and error/normal exit etc. 
     printf("eof\n"); 
     } 

     char c=getchar(); 

     if (c=='\n') { 
     // error check and error/normal exit here 
     printf("newline\n"); 

     } else if (isspace(c)) { 
     // advance and remove them - watch for end of stream when winding 
     printf("advance and discard whiitespace\n"); 

     } else { // add check for isdigit 
     // push back 
     ungetc(c, stdin); 
     printf("ungetc\n"); 
     } 

     scanf("%d", &arr[i][j]); 
     printf("got %d\n", arr[i][j]); 
    }  
    } 

    return 0; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^