【问题标题】:Length is increased while reversing a string反转字符串时增加长度
【发布时间】:2018-03-29 13:25:29
【问题描述】:

我正在研究“C 编程语言”并尝试反转 C 风格的字符串。我的理解是,像“voldemort”这样的字符串文字表示为一个由 9 个字符组成的字符数组(每个大小为 1),后跟一个空字符:

v o l d e m o r t \0
_ _ _ _ _ _ _ _ _ _

我反转字符串的想法是找到长度,然后用它来声明一个适当长度的数组,并将其定义为反向,在末尾保留一个空值。

t r o m e d l o v \0
_ _ _ _ _ _ _ _ _ _

但是,在我的反向字符串中,长度突然变长了,我没有任何运气弄清楚原因。

#include <stdio.h>

int mystrlen(char s[]);
void reverse(char original[], char reversed[], int len);

int mystrlen(char s[]) {
    int i = 0;
    while (s[i] != '\0') {
        ++i;
    }
    return i;
}

void reverse(char original[], char reversed[], int len) {
    int i, c;
    for (i = 0; i < len; ++i) {
        reversed[i] = original[len-i-1];
    }
}

int main() {
    int len;
    char test[] = "voldemort";
    len = mystrlen(test);
    char tset[len+1];
    reverse(test, tset, len);
    printf("Original: %s\n", test);
    printf("Original Length: %d\n", mystrlen(test)); // 9
    printf("Original Size: %lu\n\n", sizeof(test)); // 10

    printf("Reversed: %s\n", tset);
    printf("Reversed Length: %d\n", mystrlen(tset)); // 13 (expected: 9)
    printf("Reversed Size: %lu\n", sizeof(tset));  // 10
    return 0;
}

【问题讨论】:

  • 它是魔法,使用“你知道谁”的名字
  • 看起来你没有做任何关于 0 终止反向副本的事情......
  • @codekaizer "不可逆转的人"
  • @John3136 语句“char tset[len+1]”不是将数组初始化为全零吗?
  • @DavidStevens C 不会进行任何初始化,除非您明确告诉它这样做。 (或者,简短的回答:“不”;-)

标签: c


【解决方案1】:

一旦你反转字符串需要NUL终止

   void reverse(char original[], char reversed[], int len) {
        int i, c;
        for (i = 0; i < len; ++i) {
            reversed[i] = original[len-i-1];
        }
        reversed[i] = '\0'; //this line required
    }

输出:

Original: voldemort
Original Length: 9
Original Size: 10

Reversed: tromedlov
Reversed Length: 9
Reversed Size: 10

【讨论】:

    【解决方案2】:

    您需要将reversed 字符串归零:

    void reverse(char original[], char reversed[], int len) {
        int i, c;
        for (i = 0; i < len; ++i) {
            reversed[i] = original[len-i-1];
        }
        reversed[len] = '\0';
    }
    

    【讨论】:

      【解决方案3】:

      正如其他人所提到的,您没有以空字符终止字符串。我只是想指出,您很幸运程序能够成功运行,因为没有终止符 strlen() 将开始很好地读取字符串末尾发生的任何垃圾内存。这是不应该触及的内存,迟早你会遇到分段错误。在您的情况下,在操作系统注意到并杀死您的程序之前,该垃圾中恰好有一个空字符。

      【讨论】:

      【解决方案4】:

      因为你没有初始化 char tset[len+1];它可能包含未定义的值,并且由于您最后没有设置“\ 0”,因此它显示的是随机值。您可能需要将反向功能更改为:

      void reverse(char original[], char reversed[], int len) {
          int i, c;
          for (i = 0; i < len; ++i) {
              reversed[i] = original[len-i-1];
          }
      
          reversed[len]='\0';
      }
      

      或用 0 值初始化 tsset。

      问候

      【讨论】:

        【解决方案5】:

        函数:reverse() 未能 NUL 终止反转的字符串,因此对 mystrlen() 的第二次调用会继续计数字符,直到找到包含“\0”的某个“随机”字符

        由于此“随机”字符将超出 tset[] 数组的末尾,因此发布的代码包含未定义的行为。

        【讨论】:

        • 感谢有关 mystrlen() 计数过多的额外信息 :)
        【解决方案6】:

        您忘记添加 '\0' 字符来指示字符串的结尾。

        新的反向功能->

        void reverse(char original[], char reversed[], int len) {
            int i, c;
            for (i = 0; i < len; ++i) {
                reversed[i] = original[len-i-1];
            }
            reversed[len] = '\0';
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-25
          • 1970-01-01
          • 2018-12-20
          • 2012-07-09
          • 1970-01-01
          • 2021-03-12
          相关资源
          最近更新 更多