如何连接“常量字符串”和字符?

4
什么是以下操作的“正确方法”?(注意,我不想将消息输出到屏幕上(尚未),数据需要存储在变量中。)
std::cout << "Enter a letter: ";    
char input;
std::cin >> input;

std::string message = "Today's program was brought to you by the letter '" + input + "'.";

该代码给出了错误信息无效的操作数类型const char*const char [3]二进制operator+
我明白为什么会出现这个错误。在搜索解决方案时,建议将每个项依次转换为字符串。但是,如果您必须连接十几个项目,则变得不切实际:
std::string("x:") + x + std::string(", y:") + y + std::string(", width:") + width + std::string(", height:") + height + ...;

在C++中,将字符串、字符、字符数组和任何可转换的数据连接成一个字符串的“正确方式”是什么?是否有类似于 Python的漂亮字符串格式化功能的东西?

是的,Boost.Format有点像Python,并且有很多小型、现代化、类型安全的格式化库。 - chris
2个回答

4

您尝试的方法行不通,因为C++将您的连接视为尝试添加几个char指针。如果您将系列中的第一个元素显式转换为std::string,则应该可以解决。

请更改您的原始代码

string message = "Today's program was brought to you by the letter '" + input + "'.";

转换为:

string message = std::string("Today's program was brought to you by the letter '")
    + input + "'.";

请参考这篇SO文章,它更详细地讨论了这个问题(尽管我不知道为什么它被关闭了,因为它并不是一个真正的问题)。


但正如我在问题中提到的,如果我要将一打项目相加(例如 "a:" + a + ", b:" + b + ", c:" + c + ...),那么这不会导致大量的 std::string 强制转换吗? - IQAndreas
5
只需使用第一个元素构造一个std::stringstd::string和字符串字面值之间可以进行定义好的操作。 - David Stone
@DavidStone 哦,是的,我明白了!对第一个元素执行 + 操作会返回另一个 std::string,该类型也有定义该操作,以此类推。 - IQAndreas
1
事实上,在这种情况下,代码可以通过以“虚拟”的空字符串开头来变得更简单:std::string() + "今天的程序..." + input - IQAndreas
@IQAndreas 很好的回答。 - Tim Biegeleisen

2

有几种方法可以实现这一点,但是在实现简单性和方便性之间取得良好平衡的一种方法是使用“格式化程序”类,该类包装了std :: stringstream,如下所示:

string message = formatter() << "Today's program was brought to you by the letter '" << input << "'.";

格式化程序可以非常简单地在头文件中定义,如下所示:

#include <sstream>

class formatter {
public:
    template <typename T>
    formatter & operator<<(const T & o) {
        stream_ << o;
        return *this;
    }

    const std::string str() const { return stream_.str(); }

    operator std::string() {
            return stream_.str();
    }

private:
    std::ostringstream stream_;
};

在这里发生了什么:如果您尝试使用临时的std::stringstream()而不是上面的formatter(),它不起作用,因为:
  • std::stringstream不能隐式转换为std::string
  • 即使像这样做也不行std::string message = (std::stringstream() << "foo" << input << "bar").str();因为std::stringstream从其流操作中返回std::ostream&(而不是std::stringstream&),通常无法将ostream转换为string

格式化程序类允许您在一行中构造和使用stringstream,最少的样板文件。


1
这里的一个重要优点是,这种方法可以让您流式传输数字和其他类型,而这些类型无法直接连接到stringoperator std :: string() 可以被设置为const。 不管它值不值得 - static_cast <std :: ostringstream&>(std :: ostringstream()<< x << y << z).str()“可行”,但过于笨拙和冗长,不适合广泛使用... - Tony Delroy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接