c++ - 将特定数量的字符从 std::basic_istream 复制到 std::string

标签 c++ string stringstream

std::basic_istream 中提取特定数量的字符并将其存储在 std::string 中的安全好方法是什么?

在下面的程序中,我使用 char[] 最终获得 result,但我想避免 POD 类型并确保更安全和更易于维护:

#include <sstream>
#include <string>
#include <iostream>
#include <exception>

int main()
{
    std::stringstream inss{std::string{R"(some/path/to/a/file/is/stored/in/50/chars         Other data starts here.)"}};
    char arr[50]{};
    if (!inss.read(arr,50))
        throw std::runtime_error("Could not read enough characters.\n");

    //std::string result{arr}; // Will probably copy past the end of arr
    std::string result{arr,arr+50};

    std::cout << "Path is: " << result << '\n';
    std::cout << "stringstream still has: " << inss.str() << '\n';

    return 0;
}

备选方案:

  • 预先将整个流转换为字符串:std::string{inss.c_str()}
    • 这看起来很浪费,因为它会复制整个流。
  • 编写一个模板函数来接受char[]
    • 这仍将使用中间 POD 阵列。
  • 在循环中使用 std::basic_istream::getstd::basic_string::push_back 一起读取所需数量的字符
    • 循环看起来有点笨拙,但它确实避开了数组。

最佳答案

只需将其直接读入result 字符串即可。

#include <sstream>
#include <string>
#include <iostream>
#include <exception>

int main()
{
    std::stringstream inss{std::string{R"(some/path/to/a/file/is/stored/in/50/chars         Other data starts here.)"}};
    std::string result(50, '\0');

    if (!inss.read(&result[0], result.size()))
        throw std::runtime_error("Could not read enough characters.\n");

    std::cout << "Path is: " << result << '\n';
    std::cout << "stringstream still has: " << inss.str() << '\n';

    return 0;
}

自 C++11 起,以下关于 std::string ( from cppreference ) 内存布局的保证。

The elements of a basic_string are stored contiguously, that is, for a basic_string s, &*(s.begin() + n) == &*s.begin() + n for any n in [0, s.size()), or, equivalently, a pointer to s[0] can be passed to functions that expect a pointer to the first element of a CharT[] array. (since C++11)

关于c++ - 将特定数量的字符从 std::basic_istream 复制到 std::string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38226121/

相关文章:

c++ - 将字符转换为 ASCII 返回的数字太大

c++ - std::stringstream返回char *

c# - 字符串中的 double 或整数?

C++ 标准 : do namespace-scoped constexpr variables have internal linkage?

c++ - fcntl() 中的第三个参数是什么

c++ - 将 boost::uuid 转换为 char*

string - NSFontAttributeName 已更改为 String

python - 如何从 python 中的字符串中删除 ANSI 转义序列

c++ - 模板化运算符 << 未被识别

c++ - 什么是类型为 'System.Runtime.InteropServices.SEHException' 的未处理异常