如何强制std :: stringstream operator >>读取整个字符串而不是在第一个空格处停止?
我有一个模板类,用于存储从文本文件中读取的值:
template <typename T>
class ValueContainer
{
protected:
T m_value;
public:
/* ... */
virtual void fromString(std::string & str)
{
std::stringstream ss;
ss << str;
ss >> m_value;
}
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
我已经尝试设置/取消设置流标志,但它没有帮助.
澄清
该类是一个容器模板,可以自动转换为T类型.字符串只是模板的一个实例,它也必须支持其他类型.这就是为什么我想强制operator >>模仿std :: getline的行为.
作为家庭作业的一部分,我需要在C++中连接数组中的某些值.所以,例如,如果我有:
int v[] = {0,1,2,3,4}
Run Code Online (Sandbox Code Playgroud)
我可能需要在某个时候连接v [1] - > v [4],以便得到一个值为1234的int.
我使用stringstream工作,将值附加到stringstream然后转换回整数.但是,在整个程序中,最终将有大约300万个不同的v []排列传递给我的toInt()函数,而stringstream似乎相当昂贵(至少在处理那么多值时).它工作,但非常慢,我正在尽我所能来优化它.
有没有更好的方法在C++中连接数组中的int?我已经做了一些搜索,几乎所有地方似乎只是建议使用stringstream(这有效,但似乎正在减慢我的程序很多).
编辑:只是澄清,我确实需要结果是一个int.
是否有可能编写一个采用字符串流并使其看起来像这样的方法,
void method(string str)
void printStringStream( StringStream& ss)
{
method(ss.str());
}
Run Code Online (Sandbox Code Playgroud)
并且可以像这样调用
stringstream var;
printStringStream( var << "Text" << intVar << "More text"<<floatvar);
Run Code Online (Sandbox Code Playgroud)
我查找<<运算符,看起来它返回一个ostream&对象,但我可能读this错了或者没有正确执行它.
我真正想要的只是一种将字符串连接在一起并将其传递给函数的简洁方法.我能找到的最干净的东西是一个stringstream对象,但仍然有很多不足之处.
笔记:
我不能使用很多c++11答案,因为我在Visual Studio 2010上运行(违背我的意愿,但仍然)
我有机会Boost这么坚持下去.
只要清理这个烂摊子我就不会反对自定义方法.
编辑:
随着@Mooing Duck的回答与@PiotrNycz语法的混合我实现了我这样编写代码的目标,
try{
//code
}catch(exception e)
{
printStringStream( stringstream() << "An exception has occurred.\n"
<<" Error: " << e.message
<<"\n If this persists please contact "<< contactInfo
<<"\n Sorry for the inconvenience");
}
Run Code Online (Sandbox Code Playgroud)
这是我所希望的那样清洁和可读.
希望这有助于其他人清理写信息.
我正在使用std :: stringstream将固定格式字符串解析为值.但是,要解析的最后一个值不是固定长度.
要解析这样的字符串,我可能会这样做:
std::stringstream ss("123ABCDEF1And then the rest of the string");
ss >> std::setw(3) >> nId
>> std::setw(6) >> sLabel
>> std::setw(1) >> bFlag
>> sLeftovers;
Run Code Online (Sandbox Code Playgroud)
但是如何设置宽度以便输出字符串的其余部分?
通过反复试验,我发现这样做有效:
>> std::setw(-1) >> sLeftovers;
Run Code Online (Sandbox Code Playgroud)
但是正确的方法是什么?
是实现定义还是标准建议流的默认填充字符?
示例代码:
#include <iostream>
#include <iomanip>
#include <sstream>
int main ()
{
std::stringstream stream;
stream << std::setw( 10 ) << 25 << std::endl;
std::cout << stream.str() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
同 clang++ --stdlib=libstdc++
$ clang++ --stdlib=libstdc++ test.cpp
$ ./a.out | hexdump
0000000 20 20 20 20 20 20 20 20 32 35 0a 0a
000000c
$
Run Code Online (Sandbox Code Playgroud)
同 clang++ --stdlib=libc++
$ clang++ --stdlib=libc++ test.cpp
$ ./a.out | hexdump
0000000 ff ff ff ff ff ff ff ff 32 35 0a 0a
000000c …Run Code Online (Sandbox Code Playgroud) 以下测试程序返回不同的结果,具体取决于我使用的是libc ++还是libstdc ++.
#include <sstream>
#include <iostream>
int main()
{
int a = 0;
void* optr = &a;
void* iptr;
std::stringstream ss;
ss << optr;
std::cout << ss.str() << '\n';
ss >> iptr;
std::cout << iptr << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在OSX 10.9.2上使用Xcode 5的以下版本的clang
$ xcrun clang++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
Run Code Online (Sandbox Code Playgroud)
这是使用libstdc ++和libc ++构建时的测试输出
$ xcrun clang++ test.cpp <-- libstdc++ version
$ ./a.out
0x7fff5ec723e8
0x7fff5ec723e8
$ xcrun clang++ test.cpp …Run Code Online (Sandbox Code Playgroud) 我只是想知道clear()和str("")之间的区别是什么;
例如:
stringstream ss("Stack Overflow");
ss.clear();
ss.str("");
Run Code Online (Sandbox Code Playgroud)
我想知道潜在的技术差异.
例如,在解析文本文件时,有时这个文件有这样的东西:
keyword a string here
keyword another string
keyword
keyword again a string
Run Code Online (Sandbox Code Playgroud)
请注意,第3行有一个空字符串(无空格或空格).问题是当你执行stringstream >> laststring,而stringstream有一个空字符串(null或只是空格)时,它不会覆盖"laststring" ",它什么都不做.无论如何都要事先检查这种情况?我不想创建一个临时空字符串只是为了检查它在stringstream >>之后仍然是空的,似乎很蹩脚.
我正在使用一小段生成PDF文件的代码,我在互联网上找到了这些代码,并尝试(轻柔地)优化它,因为文件的创建需要很长时间.在分析之后,我将其缩小到以下代码:
std::ostringstream tmp;
tmp << std::hex << std::uppercase << std::setfill('0') <<
std::setw(2) << r << " " <<
std::setw(2) << g << " " <<
std::setw(2) << b;
out << tmp.str();
Run Code Online (Sandbox Code Playgroud)
在一个紧密的循环中发现,与out作为一个ostringstream之前它写入文件,基本上包含整个PDF内容.我发现那tmp.str()是在该循环中花费最多时间的行,并且在查找str()将返回流的底层字符串的C++引用时看到了.
然后,我想删除该副本并直接使用out会更快.所以我倾倒tmp并直接做了:
out << std::hex << std::uppercase << std::setfill('0') <<
std::setw(2) << r << " " <<
std::setw(2) << g << " " <<
std::setw(2) << b;
Run Code Online (Sandbox Code Playgroud)
但现在,生成的PDF文件被视为"已损坏",无法通过PDF阅读器打开,而前一个可能是.我使用两种方法(使用tmp流和没有)创建PDF 来比较行输出,但没有发现明显的差异...... …
我想std::stringstream用来创建格式化的字符串,但使用内联类,所以我没有stringstream局部变量飞来飞去.我的意思是:
#include <iostream>
#include <ostream>
#include <string>
#include <sstream>
int main(int argc, char* argv[])
{
std::string test = ((std::ostringstream&)
(std::ostringstream("") << "This is a test: " << 50.1 << "abc")
).str();
std::cout << test << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这在GCC中编译很好,但输出如下:
"0x401d0a50.1abc"
因此,似乎stringstream将第一个字符串视为指针并输出地址.随后operator<<的工作很好.
我该如何解决?谢谢!