gpt4 book ai didi

c++ - 如何干净地使用:const char* 和 std::string?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:35:50 24 4
gpt4 key购买 nike

tl:dr

How can I concatenate const char* with std::string, neatly and elegantly, without multiple function calls. Ideally in one function call and have the output be a const char*. Is this impossible, what is an optimum solution?



初始问题

到目前为止,我在 C++ 中遇到的最大障碍是它如何处理字符串。在我看来,在所有广泛使用的语言中,它处理字符串的能力最差。我见过其他与此类似的问题,这些问题的答案要么是“使用 std::string”,要么只是指出其中一个选项最适合您的情况。

然而,当尝试像在其他语言中那样动态地使用字符串时,这是无用的建议。我不能保证总是可以使用 std::string以及我必须使用 const char* 的时候我碰到了“它是恒定的,你不能连接它”的明显墙。

我在 C++ 中看到的任何字符串操作问题的每个解决方案都需要重复的多行代码,这些代码仅适用于该字符串格式。
我希望能够将任何字符集与 + 连接起来符号或使用简单的 format()函数就像我在 C# 或 Python 中一样。为什么没有简单的选择?

现在的情况

标准输出

我正在编写一个 DLL,到目前为止我已经将文本输出到 cout通过 <<运算符(operator)。到目前为止,使用以下形式的简单字符数组一切正常:
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*在一起,这不是一种选择。所以我发现这里的主要建议是使用 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 , intdouble ,我强烈认为这应该能够在一行中完成,但我无法找到任何实现它的例子。我应该和 char*一起工作吗?而不是常量变量,即使我已经读到你永远不应该改变 char* 的值那么这有什么帮助呢?

    有没有经验丰富的 C++ 程序员解决了这个问题,现在对 C++ 字符串很满意,你的解决方案是什么?没有解决办法吗?不可能吗?

    最佳答案

    构建字符串的标准方法,将非字符串类型格式化为字符串,是 string stream

    #include <sstream>

    std::ostringstream ss;
    ss << "Failure in " << __FUNCTION__ << ": foobar was " << foobar << "\n";
    SetReport(ss.str());

    如果你经常这样做,你可以编写一个可变参数模板来做到这一点:
    template <typename... Ts> std::string str(Ts&&...);
    SetReport(str("Failure in ", __FUNCTION__, ": foobar was ", foobar, '\n'));

    实现留给读者作为练习。

    在这种特殊情况下,字符串文字(包括 __FUNCTION__ )可以通过简单地一个接一个地书写来连接;并且,假设 foobarstd::string , 可以使用 + 与字符串文字连接:
    SetReport("Failure in " __FUNCTION__ ": foobar was " + foobar + "\n");

    foobar是数字类型,你可以使用 std::to_string(foobar)转换它。

    关于c++ - 如何干净地使用:const char* 和 std::string?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29941456/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com