【发布时间】:2015-07-08 14:30:33
【问题描述】:
tl:dr
如何将
const char*与std::string巧妙地连接起来 优雅地,没有多个函数调用。理想情况下在一个功能中 调用并让输出为const char*。这不可能吗,什么 是最优解吗?
最初的问题
到目前为止,我在使用 C++ 时遇到的最大障碍是它如何处理字符串。在我看来,在所有广泛使用的语言中,它对字符串的处理最差。我见过与此类似的其他问题,这些问题的答案要么是“使用std::string”,要么只是指出其中一个选项最适合您的情况。
但是,当尝试像在其他语言中使用字符串一样动态使用字符串时,这是无用的建议。我不能保证总是能够使用std::string,而在我不得不使用const char* 的时候,我遇到了“它是恒定的,你不能连接它”的明显墙。
我在 C++ 中看到的任何字符串操作问题的每个解决方案都需要重复的多行代码,这些代码仅适用于该格式的字符串。
我希望能够将任何字符集与 + 符号连接起来,或者像在 C# 或 Python 中一样使用简单的 format() 函数。为什么没有简单的选择?
现状
标准输出
我正在编写一个 DLL,到目前为止,我已经通过 << 运算符将文本输出到 cout。到目前为止,使用以下形式的简单 char 数组一切都很好:
cout << "Hello world!"
运行时字符串
现在我想在运行时构造一个字符串并将其存储在一个类中,这个类将保存一个报告一些错误的字符串,以便它们可以被其他类拾取并可能发送到cout 稍后,字符串将由函数SetReport(const char* report) 设置。所以我真的不想为此使用超过一行,所以我继续写如下内容:
SetReport("Failure in " + __FUNCTION__ + ": foobar was " + foobar + "\n"); // __FUNCTION__ gets the name of the current function, foobar is some variable
我当然马上就明白了:
-
expression must have integral or unscoped enum type和... '+': cannot add two pointers
丑陋的字符串
没错。所以我试图将两个或更多const char*s 添加在一起,这不是一个选择。所以我发现这里的主要建议是使用std::string,有点奇怪,输入"Hello world!" 不仅首先给你一个,而且让我们试一试吧:
SetReport(std::string("Failure in ") + std::string(__FUNCTION__) + std::string(": foobar was ") + std::to_string(foobar) + std::string("\n"));
太棒了!有用!但是看看那有多丑!!这是我见过的最丑陋的代码。我们可以简化为:
SetReport(std::string("Failure in ") + __FUNCTION__ + ": foobar was " + std::to_string(foobar) + "\n");
仍然可能是我每次遇到简单的单行字符串连接时最糟糕的方式,但现在一切都应该没问题吧?
转回常数
好吧,不,如果您正在处理 DLL,我经常会做一些事情,因为我喜欢单元测试,所以我需要由单元测试库导入我的 C++ 代码,您会发现当您尝试将该报告字符串设置为类的成员变量为std::string,编译器会抛出警告:
warning C4251: class 'std::basic_string<_Elem,_Traits,_Alloc>' needs to have dll-interface to be used by clients of class'
除了“忽略警告”(不好的做法!)之外,我发现的唯一真正解决此问题的方法是使用 const char* 成员变量而不是 std::string 但这并不是真正的解决方案,因为现在您必须将丑陋的串联(但动态)字符串转换回您需要的 const char 数组。但是你不能只在最后标记.c_str()(即使你为什么要这样做,因为这种连接在第二个变得更加荒谬?)你必须确保std::string 不会清理你新构建的字符串,给你留下垃圾。所以你必须在接收字符串的函数中这样做:
const std::string constString = (input);
m_constChar = constString.c_str();
这太疯狂了。因为现在我遍历了几种不同类型的字符串,使我的代码变得丑陋,添加了比应该需要的更多的行,所有这些只是为了将一些字符粘在一起。为什么这么难?
解决方案?
那么解决办法是什么?我觉得我应该能够制作一个将const char*s 连接在一起的函数,但也可以处理其他对象类型,例如std::string,int 或double,我强烈觉得这应该能够在一行中,但我找不到任何实现它的例子。我应该使用 char* 而不是常量变体,即使我已经读到您永远不应该更改 char* 的值,那么这有什么帮助?
是否有经验丰富的 C++ 程序员已经解决了这个问题并且现在对 C++ 字符串感到满意,您的解决方案是什么?没有解决办法吗?不可能吗?
【问题讨论】:
-
这一行能做到吗?
-
你可以在一行中写出这样的内容,但不能用一条语句。
-
我认为你应该能够做到这一点:
SetReport("Failure in " __FUNCTION__ ": foobar was " + foobar + "\n");,这不是+连接__FUNCTION__。 -
定义std::string operator+(const char*, const char*)可行吗?
-
@tivn Gah,所以基本上我问错了问题?我应该关闭这个。首先,为什么这会起作用?
标签: c++ string char concatenation