c++ - 连接字符串的意外行为

标签 c++ string c++11 concatenation

我试图在 C++11 中连接两个字符串,但我经常遇到意外行为。

首先,我有一个将任何类型转换为字符串的函数:

template <class T>
static inline const char * toStr(T arg) {
    stringstream ss;
    ss << arg;
    return (ss.str()).c_str();
}

然后,我像这样使用这个函数:

string measure_name;
for (unsigned long j = 0; j < 1280; j++) {
    measure_name = string("ADC_") + toStr(j);
    cout << measure_name << endl;
}

一切顺利,直到我达到一个 4 位数 (> 999): 我的变量 measure_name 通常等于“ADC_ADC_”...而且它是随机发生的。我做了一些研究,但没有发现任何关于这种奇怪行为的信息。

请注意,如果 toStr 返回 string 而不是 const char *,则此问题已解决。

此外,如果我尝试打印返回值,我从来没有看到它等于“ADC_ADC_”,所以我相信真正的问题来自连接指令:

string measure_name;
for (unsigned long j = 0; j < 1280; j++) {
    const char* tmp = toStr(j);
    if (!strcmp(toStr(j), "ADC_ADC_"))
        cout << "bug" << endl; //never happens
    measure_name = string("ADC_") + tmp; //problem comes from here
    cout << measure_name << endl;
}

我只是想了解我在那里做错了什么......我知道我使用的是非常古老的 C++,但无论如何它应该可以工作。

感谢您的帮助。

最佳答案

这里

return (ss.str()).c_str();

您正在返回一个指向临时 std::string 缓冲区的指针(从 str() 返回)。从函数返回的指针对调用者来说是无用的,因为它指向的 std::string 已经不存在了。

指针只是一个指针。如果你想要一个字符串,返回一个 std::string。如果您想返回一个 const char*,那么您需要将该字符串存储在某处并管理其生命周期。

std::string 确实管理字符数组的生命周期,所以只需:

template <class T>
static inline std::string toStr(T arg) {
    stringstream ss;
    ss << arg;
    return ss.str();
}

如果有人需要 char 的 c 数组,他们仍然可以调用 c_str(只要 std::string 就可以使用它还活着)。


考虑使用 std::to_string 而不是 toStr .

关于c++ - 连接字符串的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70152465/

相关文章:

java - 正则表达式将所有格鲁吉亚符号替换为常规拉丁符号

ios - 如何使用 swift 在数组中字符串的开头和结尾添加带双引号的字符串

java - 在 Java 中替换数据的最快方法

c++ - 为什么 int 对象和函数类型之间存在歧义?

c++ - 常量指针 C++ 和优化,它们更快吗?

iphone - 解析 OBJ 文件

c++ - 使用 C++ 在 Qt 脚本中进行异常处理?

android - QT Windows 到 Android 必要性项目变更

c++11 - 在返回右值移动期间,是否有堆栈拷贝?

c++ - 类模板中文字运算符的Friend声明