我想知道是否可以使用泛型编程将std :: vector转换为std :: stringstream,如何才能完成这样的事情?
我正在尝试编写一个函数,它将检测我几乎在字符串流的末尾,但它似乎不起作用.
这是一些代码:
std::string path(1.2.3);
int number;
std::stringstream ss(path);
while (!ss.eof()) {
if (ss.peek() != '.') {
ss >> number;
if (ss.tellg() == path.length()) {
std::cout << "Last one: " << number;
} else {
std::cout << number;
}
} else { ss.get(); }
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用ss.tellg()== path.length(),但这不起作用.有人有替代方案吗?
我在尝试使用stringstream对象时注意到了一些事情.这是一个无用的例子来解释这个:
stringstream ss ;
ss << "my string" ;
cout << ss.str() << endl ;
Run Code Online (Sandbox Code Playgroud)
不等于
cout << (stringstream() << "my string").str() << endl ;
Run Code Online (Sandbox Code Playgroud)
这会导致编译错误,抱怨'class std :: basic_ostream'没有名为'str'的成员.
我不能轻易解释这一点.这对我的应用程序并不重要,但我很确定这隐藏了一个有趣的c ++技巧.
注意:我正在使用gcc和c ++ 14
任何人都可以告诉我或指向一个简单的例子,说明如何将int附加到包含单词"Something"(或任何单词)的字符串流中?
考虑以下功能:
void f(const char* str);
Run Code Online (Sandbox Code Playgroud)
假设我想使用stringstream生成一个字符串并将其传递给此函数.如果我想在一个声明中这样做,我可能会尝试:
f((std::ostringstream() << "Value: " << 5).str().c_str()); // error
Run Code Online (Sandbox Code Playgroud)
这给出了一个错误:'str()'不是'basic_ostream'的成员.好的,所以operator <<返回ostream而不是ostringstream - 如何将它转换回ostringstream?
1)这个演员安全吗?
f(static_cast<std::ostringstream&>(std::ostringstream() << "Value: " << 5).str().c_str()); // incorrect output
Run Code Online (Sandbox Code Playgroud)
现在有了这个,结果是运算符<<("Value:")调用,它实际上调用了ostream的运算符<<(void*)并打印了一个十六进制地址.这是错的,我想要的是文字.
2)为什么operator << on临时std :: ostringstream()会调用ostream运算符?当然临时有一种'ostringstream'而不是'ostream'?
我可以施放临时强制执行正确的操作员!
f(static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << "Value: " << 5).str().c_str());
Run Code Online (Sandbox Code Playgroud)
这似乎有效并将"Value:5"传递给f().
3)我现在依赖于未定义的行为吗?演员看起来很不寻常.
我知道最好的选择是这样的:
std::ostringstream ss;
ss << "Value: " << 5;
f(ss.str().c_str());
Run Code Online (Sandbox Code Playgroud)
...但我对在一行中做这件事的行为很感兴趣.假设有人想制作一个(可疑的)宏:
#define make_temporary_cstr(x) (static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << x).str().c_str())
// ...
f(make_temporary_cstr("Value: " << 5));
Run Code Online (Sandbox Code Playgroud)
这会按预期运作吗?
考虑:
std::string s_a, s_b;
std::stringstream ss_1, ss_2;
// at this stage:
// ss_1 and ss_2 have been used and are now in some strange state
// s_a and s_b contain non-white space words
ss_1.str( std::string() );
ss_1.clear();
ss_1 << s_a;
ss_1 << s_b;
// ss_1.str().c_str() is now the concatenation of s_a and s_b,
// <strike>with</strike> without space between them
ss_2.str( s_a );
ss_2.clear();
// ss_2.str().c_str() is now s_a
ss_2 << s_b; // line ***
// ss_2.str().c_str() the value of s_a …Run Code Online (Sandbox Code Playgroud) 我正在重构一些遗留代码,这些代码使用printflongs字符串(没有任何实际的格式)来打印纯文本表标题,看起来像这样:
| Table | Column | Header |
Run Code Online (Sandbox Code Playgroud)
目前正在制作如下:
printf("| Table | Column | Header |");
Run Code Online (Sandbox Code Playgroud)
我想生成上面的代码,效果为1:
outputStream << "|" << std::setw(10) << std::center << "Table"
<< "|" << std::setw(10) << std::center << "Column"
<< "|" << std::setw(9) << std::center << "Header"
<< "|" << std::endl;
Run Code Online (Sandbox Code Playgroud)
不编译,因为<iomanip>有流操纵std::left,std::right和std::internal,但似乎并没有什么std::center.在标准C++库中是否有一种干净的方法可以做到这一点,还是我必须手动计算必要的间距?
1 即使这比C代码更冗长,但由于printf语句数量和字符串中不加重复的数量,从长远来看它将更加冗长.它也将更具可扩展性和可维护性.
我很难从以下代码中理解stringstream的不同行为.有人能否了解内部流如何工作?
int main(){
string str = "123";
stringstream ss(str);
cout << ss.str() <<endl;
ss << str;
cout << ss.str() <<endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
123
123
int main(){
string str = "123";
stringstream ss;
ss << str;
cout << ss.str() <<endl;
ss << str;
cout << ss.str() <<endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
123
123123
显然,我在这里遗漏了一些关于字符串流的重要信息,但有人可以解释原因
#include <sstream>
using namespace std;
stringstream foo() {
stringstream ss;
return ss;
}
Run Code Online (Sandbox Code Playgroud)
失败了
In file included from /usr/include/c++/4.4/ios:39,
from /usr/include/c++/4.4/ostream:40,
from /usr/include/c++/4.4/iostream:40,
from rwalk.cpp:1:/usr/include/c++/4.4/bits/ios_base.h: In copy constructor ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’:/usr/include/c++/4.4/bits/ios_base.h:790: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.4/iosfwd:47: error: within this context
/usr/include/c++/4.4/iosfwd: In copy constructor ‘std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(const std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >&)’:
/usr/include/c++/4.4/iosfwd:75: note: synthesized method ‘std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)’ first required here
/usr/include/c++/4.4/streambuf: In copy constructor ‘std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::basic_stringbuf(const std::basic_stringbuf<char, std::char_traits<char>, …Run Code Online (Sandbox Code Playgroud) 这个例程被称为无数次,以创建充满数字的大型csv文件.有没有更有效的方法来实现这一目标?
static std::string dbl2str(double d)
{
std::stringstream ss;
ss << std::fixed << std::setprecision(10) << d; //convert double to string w fixed notation, hi precision
std::string s = ss.str(); //output to std::string
s.erase(s.find_last_not_of('0') + 1, std::string::npos); //remove trailing 000s (123.1200 => 123.12, 123.000 => 123.)
return (s[s.size()-1] == '.') ? s.substr(0, s.size()-1) : s; //remove dangling decimal (123. => 123)
}
Run Code Online (Sandbox Code Playgroud)