Не могу добавить символы в указатель на символ, назначенный на "" - PullRequest
2 голосов
/ 25 апреля 2020

Скажите, у меня есть этот код

char *string = "";
string += 'A';
string += 'B';
string += 'C';
printf("%s\n", string);

Он просто печатает пустую строку. Почему это происходит, и есть ли простой способ объединить отдельные символы, начиная с пустой строки, если я не знаю, как долго это будет продолжаться?

Ответы [ 4 ]

4 голосов
/ 25 апреля 2020

В таких выражениях

string += 'A';

используется указатель арифмети c. Значение внутреннего представления символа 'A' добавляется к значению указателя string, и в результате указатель имеет недопустимое значение, поскольку он не указывает на фактический объект.

You необходимо объявить массив символов как, например,

char string[4] = "";

, а затем вы можете установить соответствующие элементы массива в символьные литералы, как, например,

int i = 0'
string[i++] = 'A';
string[i++] = 'B';
string[i++] = 'C';
string[i] = '\0';

printf("%s\n", string);

Также у вас есть опечатка в этом call

printf("&s\n", string);

Если массив символов уже содержит строку типа

char string[4] = "AB";

, и вы хотите добавить символ в конец строки, то вы можете написать символьный литерал.

size_t n = strlen( string );
string[n] = 'C';
string[n + 1] = '\0';

Или вы можете использовать строковый литерал и стандартную C функцию strcat наподобие

strcat( string, "C" );

В любом случае массив символов должен иметь достаточно места для размещения нового характер.

1 голос
/ 25 апреля 2020

string += 'A'; добавляет , а не добавляет символ к строке, увеличивает char указатель string на значение 'A', которое в системах, использующих ASCII, равно 65 и составляет string указывает далеко за конец "" строкового литерала. Следовательно, этот код имеет неопределенное поведение.

printf("&s\n", string); должен печатать &s и символ новой строки.

Если вы допустили неправильный ввод кода в вопросе, printf("%s\n", string); будет иметь неопределенное поведение, и печать возможна пустая строка, а также cra sh или любой другой неприятный побочный эффект.

Если вы хотите создать строку по одному символу за раз, используйте это:

char buf[20];
char *string = buf;
*string++ = 'A';
*string++ = 'B';
*string++ = 'C';
*string = '\0';    // set the null terminator
printf("%s\n", buf);

И наоборот, вы можете использовать strcat со строковыми литералами:

char string[20] = "";
strcat(string, "A");
strcat(string, "B");
strcat(string, "C");
printf("%s\n", string);
1 голос
/ 25 апреля 2020

string - это просто указатель на строковый литерал "", поэтому, когда вы добавляете char с помощью +, вы фактически просто перемещаете указатель, а не объединяете в строку. В C вы можете выделить достаточно большую строку и использовать strcat для добавления в нее строк:

char string[100] = "";
strcat(string, "A");
strcat(string, "B");
strcat(string, "C");
printf("%s\n", string);

Если вы хотите использовать символы, тогда вы можете преобразовать символ в строка первая.

0 голосов
/ 25 апреля 2020

Он просто печатает пустую строку.

Вы несчастливы, но неудивительно, что неопределенное поведение вашего кода проявляется в печати явно пустой строки. Это было бы более показательным для характера проблемы, если бы она вызвала segfault или какое-либо другое нарушение памяти, что было бы вполне уместно.

Почему это происходит

Поскольку вы выполняете арифметику c для указателя , а не изменяете то, на что он указывает. Это выражение ...

string += 'A';

... вычисляет сложение указателя string с целочисленной символьной константой 'A' (чье значение цифры c зависит от системы, но часто это код ASCII для заглавной буквы A), и результирующий указатель сохраняется в string. Это заставляет string указывать на нечто иное, чем это было ранее. Он никоим образом не изменяет содержимое памяти, на которую указывает string.

, и есть ли простой способ объединить отдельные символы, начиная с пустой строки, если я не знаю как долго это будет?

Если у вас есть верхняя граница того, как долго могут быть данные, тогда проще всего объявить достаточно большой массив для хранения данные и инициализировать их со всеми нулями ...

char string[MAX_LEN + 1] = {0};

Затем вы можете добавить один символ, записав его в следующий доступный индекс (какой индекс вы можете отслеживать или вычислять при необходимости с помощью strlen()):

unsigned next_index = 0;

string[next_index++] = 'A';
string[next_index++] = 'B';
string[next_index++] = 'C';

Обратите внимание, что это основано на инициализации нуля - которая не является автоматической c для локальных переменных - чтобы гарантировать, что содержимое массива всегда составляет строка с нулевым символом в конце . Сделав это, вы можете напечатать ожидаемый результат:

printf("%s\n", string);

Если вы заранее не знали разумную верхнюю границу того, какова длина строки, или если верхняя граница была чрезвычайно большой, то вы потребуется полагаться на динамическое выделение и перераспределение памяти c. Эту тему вы должны отложить на потом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...