Intereting Posts
C Указатель и распределение памяти: массивы Realloc и передача указателя Как проверить, была ли инициализирована переменная в C? Как обрабатывается условная инициализация и является ли она хорошей практикой? Ошибка проверки выполнения во время выполнения # 2 – Урон вокруг переменной «проверка» был поврежден Зачем вычесть нулевой указатель в offsetof ()? Инициализировать массив в функции Определение указателя на статическую строку В любом случае, чтобы быстро сломать слово в массив символов в объективе c? странный результат сравнения целочисленного неравенства C Правильный способ опорожнения C-String 2D-массив на CUDA Сравнение сравнений указателей с разными объектами Почему параметр endptr для strtof и strtod содержит указатель на указатель не const const? программа, которая считывает простые декларации данных и отвечает на объем памяти, который будет выделен этой переменной Рекурсия с использованием функции main ()

printf изменение строки

Использование printf для печати "\4unix\5lancs\2ac\2uk\0" Я нахожу вместо печати в виде ♦unix♣lancs☻ac☻uk , я получаю мусор ( ♫ ,►E¦§Qh ↕ ).

Я не могу найти объяснения этому; Я использую следующий метод для tokenise строки:

 /** * Encode the passed string into a string as defined in the RFC. */ char * encodeString(char *string) { char stringCopy[128]; char encodedString[128] = ""; char *token; /* We copy the passed string as strtok mutates its argument. */ strcpy(stringCopy, string); /* We tokenise the string on periods. */ token = strtok(stringCopy, "."); while (token != NULL) { char encodedToken[128] = ""; /* Encode the token. */ encodedToken[0] = (char) strlen(token); strcat(encodedToken, token); /* Add the encodedString token to the encodedString string. */ strcat(encodedString, encodedToken); /* Prepare for the next iteration. */ token = strtok(NULL, "."); } /* A null character is appended already to the encoded string. */ return encodedString; } 

И следующий код в моем драйвере для печати результата при токенизации "unix.lancs.ac.uk" :

 int main(int argc, char *argv[]) { char *foo = "unix.lancs.ac.uk"; char *bar = encodeString(foo); printf("%s\n", bar); return 0; } 

Если я добавлю printf для печати encodedString в конце метода encodeString , я не распечатаю мусор (скорее, ♦unix♣lancs☻ac☻uk дважды).

(После отладки я заметил, что содержимое реальной памяти изменено.)

Может ли кто-нибудь объяснить это явление мне?

Вы возвращаете указатель на массив encodedString , который является локальным для функции encodeString() и имеет автоматическую продолжительность хранения.

Эта память больше не действует после выхода этой функции, что и является причиной вашей проблемы.

Вы можете исправить это, предоставив encodedString статического хранения encodedString :

 static char encodedString[128]; encodedString[0] = '\0'; 

(Вы больше не можете использовать инициализатор для пустого массива, потому что массивы со статическим временем хранения сохраняют свои значения от одного вызова функции до следующего.)

Когда ты сказал:

  return encodedString; 

вы возвращаете локальную переменную, которая к тому времени, когда вы ее используете, перестанет существовать. Быстро взломать было бы сделать encodedString static.

НЕ используйте функции, возвращающие строки.

Отправьте строковый адрес в виде пареметра и измените его в функции.

Компилятор должен отобразить предупреждение. Не игнорируйте предупреждения компилятора, особенно в C.

Ваша функция должна быть такой:

 void encodeString(char *string, char *encodedString) { . . . } 

См. Здесь