[英]C: Can reverse array of chars, but not string
我做了一个简单的程序来反转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";
,我的输出没有任何结果。 怎么了?
提前致谢。
(对不起,如果这是一个总的新手问题)
sizeof "foobar"
是7 ,而不是6 。 C字符串以'\\0'
字符终止。
你的第一个例子是有效的,因为你没有NUL终止你的字符串,所以'r'
和'f'
交换。 您可能会幸运的是,反向字符串后面的地址空间评估为零(等于'\\0'
),终止字符串。 否则,打印未终止的字符串会调用未定义的行为。
使用"foobar"
,将交换'f'
和'\\0'
,并且生成的C字符串实际上将为零长度。
通过使用strlen
获取字符串的长度来解决这个问题,而不是获取内存块长度的sizeof
。 您需要包含string.h
标头。
char str[] = "foobar";
size_t str_len = strlen(str);
char rev[str_len + 1];
rev[str_len] = '\0';
for (int i = 0; i < str_len; i++)
rev[i] = str[str_len - i - 1];
printf("%s\n", rev);
在C中,字符串是以空字符结尾的字符数组。 在原始程序中, istring
不是字符串,而是一个字符数组,最后没有空字节。
在成功反转字符时, revstring
不是字符串,因为末尾没有终止空字节。 因此,当您尝试使用printf
的%s
格式说明符将其作为字符串打印时,它会搜索超出数组末尾的内容。 超出数组边界的读取是未定义的行为 。
未定义行为可以表现出来的一种方式是程序似乎正常工作。 在你的情况下,你得到了“幸运”并获得了预期的结果。
当你将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
:
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';
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.