Как читать массив строк с помощью get?

У меня есть массив из 15 строк (которые не обязательно все обязательно использовать), и несмотря на то, что везде читал, что gets ни в коем случае нельзя использовать, почему-то я считаю, что это наиболее удобно для меня для этой программы. После предложения пользователю указать, сколько строк и столбцов он хочет создать матрицу, я прошу его ввести значения матрицы, по одной строке на строку за раз. Я делаю это с помощью gets. Одновременно я хочу просмотреть строку на количество введенных пробелов, чтобы убедиться, что пользователь вводит соответствующее количество чисел, соответствующих количеству указанных столбцов.

В конце я хочу распечатать вторую строку, которую я ввел.

Вы можете предположить, что rowone и colone уже определены, я просто не копировал эту часть кода для экономии места.

int i=0, rowone, colone, sbar=0, inputs=0;
char matrixone[15][10000];
 ......

printf("input your matrix\n");

for (i=0;i<rowone;i++){
    gets(matrixone[i]);

    while(matrixone[i][inputs]!='\n'){
        if (mplier[i][inputs] == ' '){
        sbar++;
        inputs++;
        }
        else
        inputs++;

    }
    if (sbar>=colone||sbar<colone-1){
            printf("Too many/too few inputs per line\n");
            main();
        }

  sbar = 0;
  inputs = 0;

  }
  puts(matrixone[2])

Я получаю предупреждения при компиляции и, в конечном итоге, даже не могу ввести матрицу, поскольку всегда появляется сообщение «Слишком много/слишком мало входов».

Любая помощь будет принята с благодарностью, спасибо!


person stellarhawk 34    schedule 27.02.2016    source источник


Ответы (1)


Бесконечная петля.

Или, точнее, в конечном итоге matrixone[i][inputs] получает доступ далеко за пределы того, что было прочитано, и, возможно, за пределы самого массива. Это приводит к неопределенному поведению (UB).

gets() потребляет, но не сохраняет '\n'.

gets(matrixone[i]);
while(matrixone[i][inputs]!='\n'){  // why should this quit?
  ...
  inputs++;
}

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

if (fgets(matrixone[i], sizeof matrixone[i], stdin) {
  while(matrixone[i][inputs] != '\0'){
    ...
  }
}

Предложение для ОП (угадывание цели ОП)

char *matrixone[15] = { 0 };
printf("input your matrix\n");

for (i=0;i<min(rowone,15);i++){
  buf[1000];
  if (fgets( buf, sizeof buf, stdin) == NULL) break;
  buf[strcspn(buf, "\n")] = 0;

  // qualify buf concerning ' ' , sbar, etc
  ...

  matrixone[i] = strdup(buf);
}
person chux - Reinstate Monica    schedule 27.02.2016
comment
Я хочу, чтобы он останавливался, когда встречает новую строку, чтобы одна строка ввода читалась в 1 строку. Затем цикл for обеспечит повторный запуск процесса для второй строки массива. Я пытаюсь создать матрицу просто, где каждая строка ввода соответствует одной строке. Это ложный подход к нему? - person stellarhawk 34; 28.02.2016
comment
Чтобы отсечь потенциальный \n из ввода fgets(), см. завершающий символ новой строки из ввода fgets"> stackoverflow.com/questions/2693776/ - person chux - Reinstate Monica; 28.02.2016
comment
@stellarhawk 34 Я хочу, чтобы он останавливался, когда встречается с новой строкой --› Что это такое, вся программа, цикл for(), цикл while, что-то еще? - person chux - Reinstate Monica; 28.02.2016
comment
Я имею в виду, что как только встречается новая строка, я должен прекратить чтение ввода в 1-ю строку массива и перейти ко второй. И я хочу максимум 15 строк/строк. - person stellarhawk 34; 28.02.2016
comment
Код, который вы разместили в своем предложении, могу ли я спросить, что именно он делает, потому что я не очень хорошо знаком с используемым синтаксисом. - person stellarhawk 34; 28.02.2016
comment
На самом деле, с моим методом я до сих пор не понял свою ошибку. Почему бесконечный цикл? Потому что, как только пользователь нажимает ввод для новой строки, не перейдет ли он к matrixone[2][inputs], где ввод снова начинается с 0? - person stellarhawk 34; 28.02.2016
comment
@stellarhawk 34 я до сих пор не понял своей ошибки. --› Что в вашем коде останавливает цикл while(matrixone[i][inputs]!='\n')? (Ответ: появление '\n'). gets(matrixone[i]) когда-либо ставит '\n' в matrixone[i]? (Ответ: нет). - person chux - Reinstate Monica; 28.02.2016
comment
Итак, fgets может позволить мне сканировать этот \n, а затем перейти к чтению ввода для моей второй строки в массиве? - person stellarhawk 34; 28.02.2016
comment
@stellarhawk 34 Итак, fgets может позволить мне отсканировать это \n ... --› Да. - person chux - Reinstate Monica; 28.02.2016