Что за ошибка с 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?


person ash9209    schedule 12.08.2013    source источник


Ответы (3)


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

Любой размер скажем 128.

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

or

char str[128];

person P0W    schedule 12.08.2013
comment
Еще один вопрос: почему здесь не нужно приводить тип (char*) перед malloc? - person ash9209; 12.08.2013
comment
@ ash9209 malloc возвращаемый тип — void *. Он неявно преобразуется в другой тип указателя, поэтому в нем нет необходимости. - person P0W; 12.08.2013
comment
Да, я понял это. Большое спасибо. - person ash9209; 12.08.2013

Вы не выделили память для str. Замените char *str на char *str = malloc(20); для выделения кучи или char str[20] для выделения стека.

Неважно, где вы поместите * — все три утверждения идентичны.

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

person 1''    schedule 12.08.2013
comment
Когда я добавляю функцию malloc, появляется предупреждение: В функции main: предупреждение: несовместимое неявное объявление встроенной функции malloc [включено по умолчанию] - person ash9209; 12.08.2013
comment
Добавьте строку #include <stdlib.h> вверху вашей программы. - person 1''; 12.08.2013
comment
Да, я знаю, что нет необходимости упоминать текстовый редактор. Но, находясь в stackoverflow в течение достаточно долгого времени и просматривая множество вопросов, некоторые идиоты также спрашивают о редакторе. Я не знаю, что они получают от этого, хотя. - person ash9209; 12.08.2013

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

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

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

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

Что касается моего другого вопроса, положение * в char* str, char * str и char *str не имеет значения. Все 3 одинаковые.

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

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

person ash9209    schedule 12.08.2013
comment
Можно также использовать глобальную память, как в static char str[20]. Обычно это по праву осуждается, но в некоторых случаях это жизнеспособный вариант. - person chux - Reinstate Monica; 12.08.2013
comment
@ash9209 ash9209, преобразование возвращаемого значения malloc помогает следующему программисту, который прочитает ваш код. Когда stdlib.h включено, явное приведение malloc не имеет технических недостатков. - person JackCColeman; 13.08.2013