C:可以反转字符数组,但不能反转字符串

时间:2016-09-04 03:08:06

标签: c arrays string char

我做了一个简单的程序来反转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";,我的输出就没有了。怎么了?

提前致谢。

(对不起,如果这是一个全新的问题)

2 个答案:

答案 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