【问题标题】:Why does my char* copier return different things?为什么我的 char* 复印机返回不同的东西?
【发布时间】:2020-01-17 21:42:06
【问题描述】:

编写一个简单的字符串复制器并在 main() 函数中对其进行测试。奇怪的是有时程序会返回

“你好你好”

应该是这样,但也许我每运行三次,程序就会打印出来:

“你好!你好!▌▌▌▌▌▌▌▌▌▌▒“UòB╚”

为什么垃圾数据的尾部有时只添加到我的第二个字符串的末尾?

#include <iostream>
using namespace std;

int strlength(const char* c)
{
    int size = 0;
    while (*c) {
        ++c;
        ++size;
    }
    return size;
}

char* mystrdup(const char* c)
{
    int size = strlength(c);
    char* result = new char;
    copy(c, c + size, result);
    return result;      
}

void print_array(const char* c)
{
    int size = strlength(c);
    while (*c) {
        cout << *c;
        ++c;
    }
}

int main()
{
    char test[] = "Hello!";
    char* res = mystrdup(test);
    print_array(test);
    print_array(res);
}

【问题讨论】:

  • 可能您忘记添加 \0。请退出所有这些东西并使用 STL。如果此代码是您的教学课程的结果,请立即退出
  • 两个词:空终止。第二个char* result = new char;——只有一个字符?
  • 编写一个简单的字符串复制器并在 main() 函数中测试它。 -- 在一个不平凡的程序中尝试这个,你会发现维护和使用任何东西看起来这不是那么简单。如果你想提高你的技能,写一个真正的字符串class,而不是这些一次性的字符串操作例程。
  • 令人惊讶的是有多少编程课程完全忽略了编程的难点:确保程序在 25 年后仍然有效。
  • @alteredinstance 确实有用的课程,但它们应该在 C 编程课程中教授。在 C++ 课程中教授 C 语言的世界中出现了大量年轻程序员,他们认为自己了解 C++ 而实际上并不了解。

标签: c++ pointers copy c-strings garbage


【解决方案1】:

程序有未定义的行为,因为您没有为结果字符串分配足够的内存。

char* mystrdup(const char* c)
{
    int size = strlength(c);
    char* result = new char;
    ^^^^^^^^^^^^^^^^^^^^^^^           
    copy(c, c + size, result);
    return result;      
}

此外,您不会将终止零复制到结果字符串。

至少strlengthmystrdup这两个函数可以这样看

size_t strlength( const char *s )
{
    size_t size = 0;

    while ( s[size] ) ++size;

    return size;
}

char * mystrdup( const char *s )
{
    size_t size = strlength( s ) + 1;

    char *result = new char[size];

    copy( s, s + size, result );

    return result;      
}

当然,您可以使用在标头&lt;cstring&gt; 中声明的标准C 函数strcpy,而不是标准算法std::copy

strcpy( result, s );

并且不要忘记删除分配的数组。

char* res = mystrdup(test);
//…
delete [] res;

注意函数print_array没有使用变量size。无需逐个字符地输出 C 字符串。

函数可以这样定义

std::ostream & print_array( const char *s, std::ostream &os = std::cout )
{
    return os << s;
}

最后,标识符c 通常用于char 类型的单个对象。如果你处理一个字符串,那么最好使用标识符s

【讨论】:

    【解决方案2】:

    您的代码中有多个错误。您分配了错误的内存(char 而不是 char 数组)。你不会删除记忆。停止使用 C-string 并使用 std::string

    #include <iostream>
    #include <string>
    using std::cout;
    
    void print_array(const char* c)
    {
        while (*c) {
            cout << *c;
            ++c;
        }
    }
    
    int main()
    {
        std::string = "Hello!";
        std::string res = test;
        print_array(test.c_str());
        print_array(res.c_str());
    }
    

    【讨论】:

      【解决方案3】:

      在 strcpy 中你需要创建一个字符大小。

      char* mystrdup(const char* c)
      {
          int size = strlength(c);
          char* result = new char[size];
          copy(c, c + size, result);
          return result;      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-24
        • 1970-01-01
        • 2018-02-18
        • 2022-01-15
        • 2012-12-06
        • 1970-01-01
        相关资源
        最近更新 更多