我的反向字符串函数出了点问题

时间:2019-02-11 08:25:29

标签: c

所以当我反转“ hello”时它似乎起作用了,但是它打印出了一些奇怪的东西 “ol▒eh” 在中间。我修好了

i< length/2;

i<= length/2;

第一个不是正确的吗? C中的±字符是什么意思?是Null吗?

void reverse_copy(char dest[], const char src[]){
  size_t i;
  char temp;
  size_t length = (size_t)strlen(src);
  for(i = 0; i <= length/2; i++){ /*?? why i<length/2 is not working*/
    dest[i] = src[length-i-1];
    temp = src[i];
    dest[length-i-1] = temp;
  }
}

4 个答案:

答案 0 :(得分:7)

i< length/2;的主要问题在于,在src的奇数字符串长度的情况下,它可能会忽略“中间”元素。因此,dest中的中间元素可能保持未初始化状态,然后显示为某些“任意” ASCII值。

但是,通常,您的代码适用于reverse_in_place,在这里您必须注意不要覆盖以后在复制循环中需要的内容。

但是,如果您进行了reverse_copy,那么简单地进行一个反向循环就足够了,甚至更好:

void reverse_copy(char dest[], const char src[]){
  size_t i;
  size_t length = strlen(src);
  for(i = 0; i < length; i++){
    dest[i] = src[length-i-1];
  }
  dest[i] = '\0';
}

答案 1 :(得分:3)

使用:

for(i = 0; i < length/2; i++){

您永远不会在dest中设置中间字符(对于奇数长度)。

在您的示例"hello"中,length/22,因此您进行了设置(对于i = 0):

dest[0] = src[5-0-1]; // dest[0] = src[4]
dest[5-0-1] = src[0]; // dest[4] = src[0]

然后(对于i = 1):

dest[1] = src[5-1-1]; // dest[1] = src[3]
dest[5-1-1] = src[1]; // dest[3] = src[1]

就是这样。您从未设置dest[2]

答案 2 :(得分:2)

因为i<length/2已经基于整数除法,即:它将对结果取底。如果字符串长度为奇数,将跳过中间元素。

答案 3 :(得分:1)

要了解代码中发生了什么,调试器将提供帮助。 您需要逐行浏览代码,并观察ilength - i - 1的值。


中间出现一个奇怪字符的原因是,如果length为奇数,则当条件为<时,中间项将被跳过。

例如,当length == 5时为5/2 == 2(由于整数除法2.52)。 因此分析循环:

  1. i=0
  2. i < 2。是的,所以继续代码块。
  3. dest[0] = src[4]
  4. temp = src[0]
  5. dest[4] = temp
  6. i++我是1
  7. i < 2。是的,所以继续代码块。
  8. dest[1] = src[3]
  9. temp = src[1]
  10. dest[3] = temp
  11. i++我是2
  12. i < 2。不,所以退出循环

因此,在检查步骤时(尤其是步骤3、5、8、10),只有dest[0]dest[1]dest[3]dest[4]是从源中写入的<。 目的地2不变。

偶数不会出现此问题。


由于dest[2]尚未更新,因此将显示已经存在的字符。可以是任何随机字符。如果将其初始化为0(空值),则表示0的字符。

但是看着那个字符,它看起来更像是一个值177(扩展的ASCII代码:http://www.asciitable.com/


我也发现reverse_copy的定义很容易出错,因为它不知道目标缓冲区有多大。如果太小,它可以覆盖某些东西。


在这种情况下,我将使用哨兵标记字符串的结尾,并使用while循环:

void reverse_copy(char dest[], const char src[])
{
    const char* src_end = src + strlen(src) - 1;
    --src;

    while (src_end > src)
    {
        *dest = *src_end;

        ++dest;
        --src_end;
    }
    *dest = '\0';
}