Я хочу инициализировать произвольные большие строки. Это строка символов с нулевым завершением, но я не могу распечатать ее содержимое. Кто-нибудь может сказать мне, почему?
Ваше решение вызывает неопределенное поведение, поскольку *(b+1) и т. д. находятся за пределами переменной стека c. Поэтому, когда вы пишете им, вы записываете всю память, которая вам не принадлежит, что может привести к разного рода повреждениям. Кроме того, вам нужно printf("%s\n", b) (printf ожидает указатель на %s).
Решение зависит от того, что вы хотите сделать. Вы можете инициализировать указатель на строковый литерал:
const char *str1 = "moja";
Вы можете инициализировать массив символов:
char str2[] = "moja";
Это также можно записать как:
char str2[] = { 'm', 'o', 'j', 'a', '\0' };
Или вы можете вручную присвоить значения вашей строки:
Это может привести к ошибке сегментации! *(b+1), *(b+2) и т. д. относятся к незанятым областям. Сначала выделяй память, а потом пиши в нее!
Ответ 3 · рейтинг 1 · N.R.S.Sowrabh
b не хватает места для хранения всех этих символов. Выделите достаточно места, используя malloc, или объявите b массивом char.
Ответ 4 · рейтинг 1 · king_nak
Ваш код вообще небезопасен! Вы выделяете в стеке только 1 символ с помощью char c;, но записываете в него 5 символов! это приведет к переполнению стека, что может быть очень опасно.
Еще одно: вы не должны разыменовывать строку при ее печати: printf("%s\n", b);
Почему бы просто не написать const char *b = "mojo";?
Ответ 5 · рейтинг 1 · Diego Sevilla
Вам нужно выделить для него место в памяти либо с помощью malloc, либо с помощью статического массива. Здесь, в вашем коде, вы используете адрес только одного символа для хранения адресов этих символов, и других, следующих за ним. Это не определено.
Отметьте, шаг за шагом, что вы делаете. Во-первых, вы назначаете указатель на одно символьное пространство в памяти. Затем, используя *b = 'm', вы устанавливаете в этой памяти символ 'm'. Но затем вы получаете доступ к следующей позиции памяти (которая не определена, поскольку для этой позиции не зарезервирована память) для сохранения другого значения. Это не сработает.
Как это сделать?
У вас есть два варианта. Например:
char *b;
char c[5];
b = &c[0];
*b = 'm';
... //rest of your code
Это будет работать, потому что у вас есть место для 5 символов в c. Другой вариант - напрямую выделить память для b с помощью malloc:
char * b = (char*) malloc(5);
*b = 'm';
... // rest of your code
Наконец, возможно, это не то, что вы хотите, но вы можете либо инициализировать массив символов, либо указатель, используя строковый литерал:
char c[] = "hello";
const char* b = "abcdef";
Ответ 6 · рейтинг 1 · garph0
printf не печатает, потому что ожидает char*, поэтому вы должны передавать b, а не *b. Чтобы инициализировать указатель на строковую константу, вы можете сделать что-то вроде:
char *s1 = "A string"
or
char s2[] = "Another string"
или выделить буфер с помощью char *b = malloc(5), а затем записать в этот буфер (как вы это сделали, или с помощью строковых функций)
то, что вы сделали, это взяли адрес одной ячейки памяти char, а затем записали в нее, возможно, перезаписав другие переменные или инструкции и, таким образом, возможно, приведя к повреждению или сбою данных.
Ответ 7 · рейтинг 1 · Ozair Kafray
Если вы напишите следующее вместо вашего printf, он напечатает первый символ.
printf("%c\n", *b);
Чтобы у вас были произвольно большие строки, вам нужно будет использовать такую библиотеку, как bstring или напишите свой собственный.
Это потому, что в C нужно получить память, использовать ее и соответственно освободить. b в вашем случае указывает только на символ, если вы не выделяете ему память с помощью malloc. А для malloc нужно указать фиксированный размер.
Для произвольно большой строки вам необходимо инкапсулировать фактический указатель на символ в собственную структуру данных, а затем управлять ее размером в соответствии с длиной строки, которая должна быть установлена в качестве ее значения.