我做了一个简单的程序来反转C中的字符串。这是我的代码:
#include <stdio.h>
int main(){
char istring[] = {'f','o','o','b','a','r'};
char revstring[sizeof(istring)];
for(int i = 0; i < sizeof(istring); i++){
int cplace = sizeof(istring)-i-1;
revstring[cplace] = istring[i];
}
printf("%s",revstring);
return 0;
}
我的结果是预期raboof
。
现在,如果我用char istring[] = {'f','o','o','b','a','r'};
交换char istring[] = "foobar";
,我的输出就没有了。怎么了?
提前致谢。
(对不起,如果这是一个全新的问题)
答案 0 :(得分:4)
char istring[] = {'f','o','o','b','a','r'};
char revstring[sizeof(istring)+1];
for(int i = 0; i < sizeof(istring); i++){
int cplace = sizeof(istring)-i-1;
revstring[cplace] = istring[i];
}
revstring[sizeof(istring)] = '\0';
7 ,而非 6 。 C字符串以sizeof "foobar"
字符终止NUL。
您的第一个示例有效,因为您无法终止字符串,因此'\0'
和'r'
交换。您可能会因为反向字符串之后的地址空间将评估为零(等于'f'
)而终止该字符串。否则,打印一个未终止的字符串会调用未定义的行为。
使用'\0'
,"foobar"
和'f'
将被交换,您生成的C字符串实际上将为零长度。
通过使用strlen
获取字符串的长度来解决此问题,而不是'\0'
来获取内存块的长度。您需要添加sizeof
标题。
string.h
答案 1 :(得分:3)
在C中,字符串是以空字符结尾的字符数组。在原始程序中,istring
不是字符串,而是最后没有空字节的字符数组。
成功反转字符时,revstring
不是字符串,因为末尾没有终止空字节。因此,当您尝试使用%s
的{{1}}格式说明符将其打印为字符串时,它会搜索超出数组末尾的内容。超出数组范围的读数是undefined behavior。
未定义行为可以表现出来的一种方式是程序似乎正常工作。在你的情况下,你得到了幸运&#34;并得到了预期的结果。
将printf
定义为istring
时,使用包含空终止字节的字符串常量对其进行初始化。所以这个定义实际上比前一个大一个字节。
当您反转字符时,您实际上包括空字节。因此,结果数组首先包含空字节,然后是其他字符。然后当你打印它时,首先看到空字节,所以你拥有的是一个空字符串。
在循环中,使用istring[] = "foobar";
代替strlen(istring)
作为上限。然后在末尾添加空字节。
sizeof(istring)
如果将char istring[] = "foobar";
char revstring[sizeof(istring)];
for(int i = 0; i < strlen(istring); i++){
int cplace = strlen(istring)-i-1;
revstring[cplace] = istring[i];
}
revstring[strlen(istring)] = '\0';
定义为字符数组,则需要在istring
分配一个额外字节,并在检查上限时保留revstring
:
sizeof