2015-01-09 4 views
2

Вопрос простой, как мне сохранить матрицу из stdin в 2d-массив. Проблема заключается в том, что я не знаю, размер, а также я должен признать плохое входные данныеКак читать матрицу из stdin в c

Пример правильного ввода:

1 2 3 
4 5 6 
7 8 9 

Пример неправильного ввода:

1 2 3 
4 5 6 5 
7 8 9 

1 2 3 4 

Сначала я пытаюсь прочитать значение одного размер массива до EOF с помощью scanf, а затем создать массив 1d array 2d. Это нормально ? Я не знаю, как scanf распознает новую строку.

+3

сочетание [ 'fgets()'] (http://linux.die.net/man/3/fgets), ['strtok()'] (http://linux.die.net/man/3/strtok) и ['malloc()'/'calloc()'] (http://linux.die.net/man/3/malloc) решит вашу проблему. –

+1

Вы не можете использовать 'scanf' для распознавания конца строки, он может распознавать пробелы (включая новые строки, вкладки и пробелы). Вместо этого вы можете использовать, например. 'fgets', чтобы получить строку, а затем разделить эту строку (используя, например,' strtok') в пространстве, чтобы получить отдельные значения в строке. –

+1

Однако есть большая проблема, я думаю: если вы не знаете размеры матрицы, как бы вы знали, что первая строка верна? Или будет ли количество значений в первой строке указывать размеры? Будут ли размеры всегда равными NxN, или это может быть MxN? –

ответ

4
  1. Использовать fgets() читать до конца строки.
  2. Разбейте линию, используя strtok() и пространство как разделитель
  3. Теперь преобразовать каждый маркер в целое, используя strtol()
  4. Возвращаемое значение может быть сохранено в массиве.
  5. Подсчитайте количество токенов, успешно преобразованных в целые числа, и сохраните счет
  6. Выделите память на основе счета.
  7. Если число равно нулю, то там не было целых чисел, и вы можете изящно игнорировать строку.

Использование malloc() сначала выделить память в массив, и вы можете увеличить размер массива на основе ввода с использованием realloc()

+0

Если OP хочет знать о некорректном вводе, OP, вероятно, должен использовать 'strtol' вместо' atoi', так как нет способа узнать, вводите ли вы неправильный ввод 'atoi'. –

+0

Функция ['strtol'] (http://en.cppreference.com/w/c/string/byte/strtol) имеет аргумент, позволяющий различать полностью допустимый ввод (например,' '123" '), частично допустимый ввод (например, «123abc») или полностью недопустимый ввод (например, «abc»). Используя 'atoi', нельзя различать два первых (« 123 »и« 123abc »), а также различать недействительные и нулевые (« abc »и« 0 »). –

0

Согласно this documentation, scanf читает строку, помеченную пробелами, включая новые символы строки. Нет необходимости явно проверять символы конца строки. Для описанной задачи достаточно просто прочитать нужное количество элементов.

+0

Если вы вообще собираетесь искать 'scanf()' i will ___strongly___, рекомендуем для проверки возвращаемого значения из первых рук. –

0

Если это не является проблемой для вас, вы можете прочитать в 1d массиве, получить размер матрицы N = SQRT (elementsCount) и в ваших элементах доступа кода, как это:

array[row*N + col]; //its equivalent of array2d[row][col] from 2d array 

или вы можете прочитать его в 1d массива, то Alloc матрицу и скопировать значения здесь.

также, если новая строка в stdin всегда означает новую строку в матрице, вы можете прочитать ее в массиве 2d и динамически перераспределить ее в процессе.

Я бы рекомендовал первый подход

// редактировать, конечно, первые два решения работает для матриц NxN. Если может быть матрица MxN, вам нужно использовать третий подход

+0

Да, когда вы читаете 9 номеров на одной строке? Ваше первое решение будет думать, что это матрица 3x3, что не так – hudi

+0

с моим первым решением, которое вам нужно прочитать всего ввода, а затем рассчитать размер матрицы, поэтому линии не имеют значения. –

0

Я стараюсь сделать это с помощью gopl sollution. Я пропускаю некоторую проверку против размера и использую константу, потому что теперь я не забочусь о распределении. Важно только чтение из stdin. Таким образом, это правильное решение, как читать матрицу из стандартного ввода строка за строкой, которая в конечном EOF

#include <stdio.h> 
#include <string.h> 

#define BUFFERSIZE 10000 

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


    char * pch; 
    int matrix[25][25]; 
    int row = 0, column = 0; 

    char buffer[BUFFERSIZE]; 
    printf("Enter a matrix: \n"); 
    while (fgets(buffer, BUFFERSIZE, stdin) != NULL) { 
     pch = strtok(buffer, " "); 
     column = 0; 

     while (pch != NULL) { 
      int li1 = strtol(pch, NULL, 10); 
      pch = strtok(NULL, " "); 
      matrix[row][column] = li1; 
      column++; 
     } 
     row++; 
    } 
    printf("Number: %dvs%d\n", row, column); 
    return 0; 
} 
Смежные вопросы