将特定数量的字符从 std::basic_istream 复制到 std::string
Copy specific number of characters from std::basic_istream to std::string
从 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::get
与std::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, '[=10=]');
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)
从 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::get
与std::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, '[=10=]');
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 abasic_string s
,&*(s.begin() + n) == &*s.begin() + n
for anyn
in[0, s.size())
, or, equivalently, a pointer tos[0]
can be passed to functions that expect a pointer to the first element of aCharT[]
array. (since C++11)