Использование 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) { . . . }
См. Здесь