printf修改字符串

使用printf打印"\4unix\5lancs\2ac\2uk\0"我发现,而不是以♦unix♣lancs☻ac☻ukforms的打印,我得到垃圾( ♫ ,►E¦§Qh ↕ )。

我无法找到解释; 我使用以下方法来标记字符串:

 /** * 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; } 

如果我在encodeString方法的末尾添加一个printf来打印encodedString ,我就不会打印出垃圾了(相反, ♦unix♣lancs☻ac☻uk两次)。

(调试时我注意到实际的内存内容已经改变。)

谁能向我解释这个现象?

您正在返回一个指向数组encodedString的指针,该数组是encodeString()函数的本地数据,并具有自动存储持续时间。

该函数退出后,此内存不再有效,这是导致问题的原因。

您可以通过赋予encodedString静态存储持续时间来修复它:

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

(您不能再使用初始化器来清空数组,因为具有静态存储持续时间的数组会从函数的一次调用到下一次调用它们保持其值。)

当你说:

  return encodedString; 

你正在返回一个局部变量,当你使用它时它将不复存在。 快速破解就是将encodedString设为静态。

不要使用返回字符串的函数。

将字符串地址作为参数发送并在函数中更改它。

编译器应显示警告。 不要忽略编译器警告,特别是在C.

你的function应该是这样的:

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

看到这里