Локальные переменные, определенные внутри func если только они явно не инициализированы, имеют неопределенное значение . Для указателей это означает, что они указывают на случайное местоположение. Использование любой неинициализированной переменной, за исключением ее инициализации, приводит к undefined behavior.
Что происходит, так это то, что fgets
будет использовать (неинициализированный и, казалось бы, случайный) указатель и использовать его для записи в память, на которую указывает. Эта память в большинстве случаев не принадлежит вам или вашей программе и может даже перезаписать некоторые другие важные данные. Это может привести к сбоям или другому странному поведению или результатам.
Самое простое решение сделать str
массив из массивов символов, как
#define NUM_OF_STRINGS 2
#define STRING_LENGTH 64
...
char str[NUM_OF_STRINGS][STRING_LENGTH];
...
fgets(str[i], sizeof str[i], stdin);
Вы должны убедиться, что выше STRING_LENGTH
достаточно, чтобы соответствовать каждой строки включая символ новой строки и строки терминатор. В случае того, что я показываю выше, это 64
, что означает, что вы можете иметь строки длиной не более 62 символов.
Теперь, как и для другой проблемы я указал, с первым вызовом fgets
чтения пустой строки.
Если у вас есть вход
2 2
hello
вход хранится в буфере памяти, а затем scanf
и fgets
читает из этого буфера.Буфер, с выше входом, посмотреть что-то вроде этого
+----+----+----+----+----+----+----+----+----+
| 2 | 2 | \n | h | e | l | l | o | \n |
+----+----+----+----+----+----+----+----+----+
После scanf
вызова прочитать два номера входного буфера выглядит как
+----+----+----+----+----+----+----+
| \n | h | e | l | l | o | \n |
+----+----+----+----+----+----+----+
Так что самый первый вызов fgets
в цикл увидит новую строку. Таким образом, он считывает эту новую строку, а затем ее выполняет, оставляя строку "hello\n"
в буфере для второй. Позвоните по номеру fgets
.
Существует несколько способов решения этой проблемы. Я лично предпочитаю использовать fgets
универсально для чтения строк, и если вам нужен простой синтаксический анализ строки, используйте sscanf
(обратите внимание на ведущий s
, также пожалуйста, see here for a good reference of all scanf
variants).
Другой способ - просто прочитать символы с входа, по одному символу за раз и отбросить их. Когда вы читаете новую строку, остановите цикл и продолжите работу с остальной частью программы.
Используйте fgets(), а затем strtok(), чтобы разбить строку вверх. –
Что касается вашей * текущей * проблемы, то аварии вы получаете, теперь подумайте немного. Вы объявляете массив указателей на 'char', но вы никогда не делаете эти указатели на самом деле * точкой * в любом месте. –
Привет, Мэтт. Спасибо за ответ. Я новичок в c. Я не знаю, как использовать strtok(). Я сейчас посмотрю. – chrisgjh