【问题标题】:Strange characters appear when using strcat function in C++在 C++ 中使用 strcat 函数时出现奇怪的字符
【发布时间】:2010-12-23 15:24:25
【问题描述】:

我是 C++ 新手,正在学习 MSDN C++ Beginner's Guide。

在尝试使用 strcat 函数时,它可以工作,但我得到三个奇怪的字符 开始。

这是我的代码

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int main() {
    char first_name[40],last_name[40],full_name[80],space[1];
    space[0] = ' ';
    cout << "Enter your first name: ";
    gets(first_name);
    cout << "Enter your last name: ";
    gets(last_name);
    strcat(full_name,first_name);
    strcat(full_name,space);
    strcat(full_name,last_name);
    cout << "Your name is: " << full_name;
    return 0;
}

这是输出

Enter your first name: Taher
Enter your last name: Abouzeid
Your name is: Y}@Taher Abouzeid

我想知道为什么 Y}@ 出现在我的名字之前?

【问题讨论】:

  • 啊啊啊! gets()它离我们远点!它烧伤了我们!

标签: c++ strcat


【解决方案1】:

您没有通过将第一个字符设置为 '\0' 来初始化 full_name,因此其中有垃圾字符,并且当您 strcat 时,您是在垃圾字符之后添加新数据。

【讨论】:

    【解决方案2】:

    您正在创建的数组中充满了随机数据。 C++ 将为数据分配空间,但不会用已知数据初始化数组。 strcat 会将数据附加到字符串的末尾(第一个 '\0'),因为字符数组尚未初始化(并且充满随机数据),这将不是第一个字符。

    这可以通过替换来纠正

    char first_name[40],last_name[40],full_name[80],space[1];
    

    char first_name[40] = {0};
    char last_name[40] = {0};
    char full_name[80] = {0};
    char space[2] = {0};
    

    = {0} 会将第一个元素设置为字符串终止符 '\0',c++ 将自动用 '\0' 填充所有未指定的元素(前提是至少指定了一个元素)。

    【讨论】:

    • 稍作修改即可使用。我替换了字符空间;字符空间[2] = {0};这很完美。请在答案中更改它,以便我可以接受。
    【解决方案3】:

    变量full_name 在被追加之前没有被初始化。

    改变这个:

    strcat(full_name,first_name);
    

    到这里:

    strcpy(full_name,first_name);
    

    【讨论】:

    • 另外,space 不是以 null 结尾的。
    • 是的。 space 数组需要定义大小为 2 并使用字符串 " " 而不是字符 ' ' 进行初始化。
    【解决方案4】:

    您在测试中看不到任何问题,但您的space 字符串在使用' ' 初始化其唯一字符后也不是空终止的。

    【讨论】:

      【解决方案5】:

      正如其他人所说,你必须初始化数据,但你有没有想过学习标准的c++库?它有时更直观,而且可能更有效。

      有了它会是:

      string full_name=first_name+" "+last_name;
      

      而且您不必为终止空字符而烦恼。如需参考,请转到cplusplus

      哦,还有一个完整的工作示例,以便您更好地理解(来自 operator+=):

      #include <iostream>
      #include <string>
      using namespace std;
      
      int main ()
      {
        string name ("John");
        string family ("Smith");
        name += " K. ";         // c-string
        name += family;         // string
        name += '\n';           // character
      
        cout << name;
        return 0;
      }
      

      【讨论】:

        【解决方案6】:

        问题在于您的 space 文本。

        strcat 函数需要一个 C 风格的字符串,它是零个或多个字符,后跟一个空字符,终止字符。因此,在为 C 风格字符串分配数组时,需要为终止空字符分配一个额外的字符。

        所以,你的space array needs to be of length 2, one for the space character and one for the null character.

        由于space 是常量,因此您可以使用字符串文字而不是数组:

        const char space[] = " ";

        另外,由于您是新手,这里有一些提示:
        1. 每行声明一个变量。
        这将更容易修改和更改变量类型。

        2. 刷新std::cout,使用std::endl,或包含'\n'。
        这将刷新缓冲区并显示任何剩余的文本。

        3. 阅读 C++ 语言常见问题。
        Click here for the C++ language Frequently Asked Questions (FAQ)

        4. 使用 std::string 可以避免 C 风格的字符串问题

        5. 购买 Scott Myers Effective C++More Effective C++ 书籍。

        【讨论】:

          【解决方案7】:

          字符串在 C 和 C++ 中以 null 结尾(strcat 函数是 C 的传统)。这意味着当您指向一个随机内存地址时(新的 char[] 变量指向一个堆栈地址,其中包含未初始化的随机内容),编译器会将第一个 \0(空)字符之前的所有内容解释为字符串(如果您使用指针算法,将超出分配的大小)。

          这可能会导致非常模糊的错误、安全问题(缓冲区溢出漏洞利用)以及非常不可读和不可维护的代码。现代编译器具有有助于检测此类问题的功能。

          这里是a good summary of your options

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-14
            • 1970-01-01
            • 1970-01-01
            • 2016-01-11
            • 1970-01-01
            相关资源
            最近更新 更多