2013-08-12 2 views
0

Где я ошибаюсь и почему?Какая ошибка с fgets в этом коде?

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

int main() 
{ 
char *str; 
int length, i, j, flag = 0; 

printf("\n\nEnter string: "); 
fgets(str, 20, stdin); 
printf("You entered: %s", str); 
    return 0; 
} 

Там проблема с линией fgets(str, 20, stdin); линии. Я не могу разобраться. После ввода строки компилятор просто перестает работать, и я получаю сообщение об ошибке: Эта программа перестала работать. Не могли бы вы указать, где я ошибаюсь, а также обходной путь для этой проблемы? Стандартная библиотека определяет fgets как:

char * fgets (char * str, int num, FILE * stream); 

Я использую Sublime Text 2 и GCC на MinGW оболочки.

Другой вопрос, основанный на концепции указателя: Существуют ли различия между char * str, char* str и char *str?

ответ

1

Так, отвечая на мой собственный вопрос, код, который я отправил вызывает ошибку, потому что я не выделяю память для переменной с именем str. Я просто даю ему произвольное место памяти.

Таким образом, чтобы приведенный выше код работал правильно, мы можем либо выделить память в стеке, либо в кучу.

Для размещения в стеке используйте char str[20] и для выделения памяти в куче используйте char *str = malloc(20) или char *str = malloc(20*sizeof(char)).

Не беспокойтесь о деталях, если вы не знаете о стеке или куче. Любой из них будет использоваться для простых консольных программ.

Как мой другой вопрос, позиция * в char* str, char * str и char *str не имеет значения. Все три из них одинаковы.

Другой вопрос, который я задал в связи с ответом @ P0W, состоял в том, почему мы не выбрасываем адрес памяти, который возвращается malloc в char *str = malloc(20*sizeof(char)). Ответ на этот вопрос заключается в том, что это необязательно и его следует избегать в C. Включите заголовочный файл stdlib.h, чтобы получить обходной путь.

Проверьте это StackOverflow question для получения более подробной информации. Или вы также можете посмотреть C FAQ section.

+0

Также можно использовать память _global_ как в 'static char str [20]'. Как правило, это по праву недооценивается, но в отдельных случаях это жизнеспособный вариант. – chux

+0

@ ash9209, приведение возвращаемого значения 'malloc' помогает следующему программисту, который читает ваш код. Когда включен 'stdlib.h', нет никакого технического недостатка для явного литья 'malloc'. – JackCColeman

1

Вы не указали какую-либо область памяти для: str. Замените char *str на char *str = malloc(20); для распределения кучи или char str[20] для распределения стека.

Не имеет значения, где вы размещаете * - все три оператора идентичны.

P.S. Sublime Text 2 - это просто текстовый редактор, и какой текстовый редактор не влияет на программу. Однако компилятор и ОС имеют значение.

+0

Показывает предупреждение при добавлении функции malloc: ** В функции «main»: предупреждение: несовместимое неявное объявление встроенной функции «malloc» [включено по умолчанию] ** – ash9209

+0

Добавить строку '#include 'в верхней части вашей программы. –

+0

Да, я знаю, что нет необходимости упоминать текстовый редактор. Но находясь на stackoverflow в течение довольно долгого времени, и просматривая множество вопросов, некоторые идиоты тоже спрашивают об этом редакторе. Однако я не знаю, что они из этого выходят. – ash9209

4

Вам нужно выделить память для str

Любой размер говорят 128.

char *str = malloc(128*sizeof(char));

или

char str[128];

+0

Еще один вопрос: почему нам не нужно приписывать тип ** (char *) ** до ** malloc ** здесь? – ash9209

+0

@ ash9209 Тип возврата malloc '' void * '. Он неявно преобразован в другой тип указателя, поэтому он не нужен. – P0W

+0

Да, я это понял. Спасибо. – ash9209