我知道其中一个优点std::stringstream是std::istream它可以接受来自任何类型的输入,这些类型定义operator<<为std::istream基元类型,也来自基元类型.
我不打算用operator<<; 相反,我只是要连接许多字符串.实现是否std::stringstream比std::string连接多个字符串更快?
如果我有一个缓冲区,如:
uint8_t buffer[32];
Run Code Online (Sandbox Code Playgroud)
并且它完全被值填充,我怎么能用十六进制表示法将它变成字符串流,在小值上用0填充?
我试过了:
std::stringstream ss;
for (int i = 0; i < 32; ++i)
{
ss << std::hex << buffer[i];
}
Run Code Online (Sandbox Code Playgroud)
但是当我从字符串流中取出字符串时,我遇到了一个问题:值<16的字节只需要一个字符来表示,我希望它们是0填充的.
例如,如果数组中的字节1和2是{32} {4},我的字符串流将具有:
204 instead of 2004
Run Code Online (Sandbox Code Playgroud)
我可以将格式化应用于stringstream以某种方式添加0-padding吗?我知道我可以用sprintf做到这一点,但是这些流已经被用于获取大量信息,并且以某种方式实现这一点将是一个很大的帮助.
我有兴趣讨论用于stringstream解析具有多种类型的行的方法.我将从查看以下行开始:
"2.832 1.3067 nana 1.678"
Run Code Online (Sandbox Code Playgroud)
现在让我们假设我有一个有多个strings和的长行doubles.解决这个问题的显而易见的方法是将字符串标记化,然后检查转换每个字符串.我有兴趣跳过第二步,stringstream直接使用只找到数字.
我认为解决这个问题的好方法是读取字符串并检查是否failbit已设置,如果我尝试将字符串解析为double,它将会是这样.
说我有以下代码:
string a("2.832 1.3067 nana 1.678");
stringstream parser;
parser.str(a);
for (int i = 0; i < 4; ++i)
{
double b;
parser >> b;
if (parser.fail())
{
std::cout << "Failed!" << std::endl;
parser.clear();
}
std::cout << b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它将打印出以下内容:
2.832
1.3067
Failed!
0
Failed!
0
Run Code Online (Sandbox Code Playgroud)
我没有惊讶它没有解析一个字符串,但内部发生了什么,以至于它无法清除它failbit并解析下一个数字?
我有一堆整数,我把它放进去了stringstream.现在我想将stringstreams改为strings,同时保持s的恒定精度string.我该怎么办?我知道我可以使用stringstreams.precision(),但由于某些原因它不起作用:
float a = 5.23;
float b = 3.134;
float c = 3.0;
std::stringstream ta;
std::stringstream tb;
std::stringstream tc;
ta << a;
tb << b;
tc << c;
ta.precision(2);
tb.precision(2);
tc.precision(2);
std::string out = "";
out += ta.str() + "\n";
out += tb.str() + "\n";
out += tc.str() + "\n";
Run Code Online (Sandbox Code Playgroud)
会回来5.23\n3.134\n3.0,而不是5.23\n3.13\n3.00
我何时应该使用stringstream而不是string::append()?假设我要安排字符串.
stringstream ss;
ss << str1 << "str2" << ...
Write(ss.str());
Run Code Online (Sandbox Code Playgroud)
要么:
string str;
str.reserve(10000);
str.append(str1);
str.append("str2");
...
Write(str);
Run Code Online (Sandbox Code Playgroud)
哪个更快?
我有std::stringstream对象ss1.现在,我想从这个创建另一个副本.
我试试这个:
std::stringstream ss2 = ss1;
Run Code Online (Sandbox Code Playgroud)
要么:
std::stringstream ss2(ss1)
Run Code Online (Sandbox Code Playgroud)
既不起作用
错误消息是这样的:
无法从bsl :: basic_stringstream,bsl :: allocator> :: basic_stringstream(const bsl :: basic_stringstream,bsl :: allocator>&)访问std :: ios :: basic_ios(const std :: ios&).
如何让这个简单的类移动?我认为是正确的只会产生一堵错误之墙......
#include <iostream>
#include <sstream>
#include <utility>
class message
{
public:
message() = default;
// Move constructor
message( message &&other ) :
stream_( std::move( other.stream_ ) ) // Nope
{}
// Move assignment
message &operator=( message &&other )
{
if ( this != &other )
{
stream_ = std::move( other.stream_ ); // Nope #2
}
return *this;
}
private:
message( const message & ) = delete;
message &operator=( const message & ) = delete;
std::stringstream stream_;
// Other member variables …Run Code Online (Sandbox Code Playgroud) 我想建立std::string一个std::vector<std::string>.
我可以使用std::stringsteam,但想象有一个更短的方式:
std::string string_from_vector(const std::vector<std::string> &pieces) {
std::stringstream ss;
for(std::vector<std::string>::const_iterator itr = pieces.begin();
itr != pieces.end();
++itr) {
ss << *itr;
}
return ss.str();
}
Run Code Online (Sandbox Code Playgroud)
我怎么可能这样做?
我有一个vector包含strings遵循格式的text_number-number
例如: Example_45-3
我只想要第一个数字(45在示例中),而不是我能用当前代码做的其他事情:
std::vector<std::string> imgNumStrVec;
for(size_t i = 0; i < StrVec.size(); i++){
std::vector<std::string> seglist;
std::stringstream ss(StrVec[i]);
std::string seg, seg2;
while(std::getline(ss, seg, '_')) seglist.push_back(seg);
std::stringstream ss2(seglist[1]);
std::getline(ss2, seg2, '-');
imgNumStrVec.push_back(seg2);
}
Run Code Online (Sandbox Code Playgroud)
是否有更简化和更简单的方法来做到这一点?如果是的话,他们是什么?
我纯粹是出于在一天结束时学习如何更好地编写代码的愿望,上面的代码确实成功地提取了第一个数字,但它看起来很长并且很圆润.
我std::stringstream广泛使用在我的应用程序中构造字符串和错误消息.在stringstreams通常寿命很短的自动变量.
这样的使用会导致每个变量的堆重新分配吗?我应该从临时stringstream变量转换为类成员变量吗?
在后一种情况下,我该如何保留stringstream缓冲区?(我应该用足够大的字符串初始化它还是有更优雅的方法?)
c++ ×10
stringstream ×10
string ×4
stl ×2
c++11 ×1
g++ ×1
iomanip ×1
iostream ×1
performance ×1
stdstring ×1