Reputation: 11002
What is a good, safe way to extract a specific number of characters from a std::basic_istream
and store it in a std::string
?
In the following program I use a char[]
to eventually obtain result
, but I would like to avoid the POD types and ensure something safer and more maintainable:
#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;
}
Alternatives:
std::string{inss.c_str()}
char[]
std::basic_istream::get
in a loop to read the required number of characters together with std::basic_string::push_back
Upvotes: 3
Views: 2005
Reputation: 9602
Just read it directly into the result
string.
#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;
}
Since C++11, the following guarantee about the memory layout of the 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)
Upvotes: 3