当我会用std::istringstream,std::ostringstream以及std::stringstream为什么不应该我只是用std::stringstream在所有情况(是否有任何的运行时性能问题?).
最后,这有什么不好的(而不是使用流):
std::string stHehe("Hello ");
stHehe += "stackoverflow.com";
stHehe += "!";
Run Code Online (Sandbox Code Playgroud) 我在Eclipse中编码并具有以下内容:
#include <ftream>
#include <iostream>
void read_file(){
char buffer[1025];
std::istringstream iss(buffer);
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试构建时,我收到以下错误: variable 'std::istringstream iss' has initializer but incomplete type
有什么想法?我已经google了一下,似乎大多数有这个问题的人根本没有包含正确的头文件我相信我做的正确.
我有一个用于读取浮点数的文件的代码存储在这样的行:"3.34 | 2.3409 | 1.0001 | ... | 1.1 |".我想使用istringstream读取它们,但它不能像我期望的那样工作:
string row;
string strNum;
istringstream separate; // textovy stream pro konverzi
while ( getline(file,row) ) {
separate.str(row); // = HERE is PROBLEM =
while( getline(separate, strNum, '|') ) { // using delimiter
flNum = strToFl(strNum); // my conversion
insertIntoMatrix(i,j,flNum); // some function
j++;
}
i++;
}
Run Code Online (Sandbox Code Playgroud)
在标记点,行仅在第一次被复制到单独的流中.在下一次迭代中,它不起作用,它什么都不做.我希望在每次迭代中都不需要构造新的istringstream对象就可以使用更多次.
我发现gcc(4.9.2)和clang(3.5.0)之间的行为有所不同,令我感到惊讶.
当我尝试unsigned int从一个std::istringstream带有负值的初始值(在示例中为"-15")中提供一个时,我得到了
fail()clang ++ 出错(带位)signed(-15)用gcc ++ 初始化我准备了以下示例程序.
#include <sstream>
#include <iostream>
int main ()
{
std::istringstream iss("-15");
unsigned int ui;
iss >> ui;
std::cout << "ui[" << ui << "] signed(ui)[" << signed(ui)
<< "] flags[" << iss.fail() << iss.good() << iss.bad()
<< iss.eof() << "]\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用clang ++,我获得以下输出
ui[0] signed(ui)[0] flags[1001]
Run Code Online (Sandbox Code Playgroud)
使用g ++,我获得以下输出
ui[4294967281] signed(ui)[-15] flags[0001]
Run Code Online (Sandbox Code Playgroud)
我有两个问题.
首先是显而易见的:谁是对的?clang ++,g ++还是一个未定义的行为?
第二个是:我如何强制gcc ++的行为类似于clang ++,从一个以减号开头的字符串中提取无符号值时会出错?
谢谢,抱歉我的英语不好.
编辑2016.04.03
我意识到这不是g ++和clang ++之间的区别,而是libstd …
我有一个do_something从流中读取无符号字符的函数。
可以从给定文件名的文件创建流。或者它可以通过将给定的字符串视为数据来创建。我想在这两种情况下重用该功能。
下面的代码在第二种情况下给出了一个错误:“错误 C2664: 'do_something: 无法将参数 1 从 'std::basic_istringstream' 转换为 'std::basic_istream'”。
这样做的正确方法是什么?
static void do_something(std::basic_istream<unsigned char>& in)
{
in.get();
}
static void string_read(unsigned char* in)
{
std::basic_ifstream<unsigned char> file(std::string("filename"));
do_something(file);
std::basic_istringstream<unsigned char> str(std::basic_string<unsigned char>(in));
do_something(str);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试istringstream将一个简单的字符串拆分为一系列整数:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main(){
string s = "1 2 3";
istringstream iss(s);
while (iss)
{
int n;
iss >> n;
cout << "* " << n << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我得到:
* 1
* 2
* 3
* 3
Run Code Online (Sandbox Code Playgroud)
为什么最后一个元素总是出现两次?怎么解决?
因此istringstream,在初始化时复制字符串的内容,例如
string moo("one two three four");
istringstream iss(moo.c_str());
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法std::istringstream使用给定c_str的缓冲区而不复制东西.这样,在传递std::istringstream&给istream&作为参数的函数之前,它不必复制大量内存.
我一直在努力做的是转换一些只接受std::ifstream&参数的函数(它们主要是解析器)istream&.我是否必须为此创建自己的istream子类?
我正在从文本文件中读取数据,并逐行使用std::getline.默认情况下,这会读取换行符\n.我的代码依赖于此.
然而,事实证明我必须处理可能在不同环境中生成的数据,即换行符是\r(Mac),\n(Unix)或\r\n(Windows)
是否有一个简单的解决方案,以便我可以做类似的事情
std::getline(data,str,'\r\n','\r','\n');
Run Code Online (Sandbox Code Playgroud)
但得到它首先寻找\r\n,然后\r和\n使之独立任何环境中生成它返回一个"行"?
或者更一般地说:std::getline对于任何类型的常用换行/回车,有没有办法用来返回"线"?
目前我所想出的就是
std::vector<int> size(3);
for (int i=0;i<3;i++){
data.open(c_string_file_name);
switch (i){
case 0: std::getline(data,str,'\r\n');size[0]=str.size();break;
case 1: std::getline(data,str,'\r');size[1]=str.size();break;
case 2: std::getline(data,str,'\n');size[2]=str.size();break;
}
data.close();
}
int min=std::min_element(size.begin(),size.end());
std::string delim;
switch (min){
case 0:delim='\r\n';break;
case 1:delim='\r';break;
case 2:delim='\n';break;
}
if ((size[0]==size[1])&&(min==1)){
delim='\r\n';
}
//rest of code use
std::getline(data,str,delim.c_str());
Run Code Online (Sandbox Code Playgroud)
基于以下假设:假设存在换行符,相关定界符将产生最短的"行".还要考虑这样一个事实,即如果它是一个分隔符\r,\r\n它将具有相同的长度字符串\r\n
保存在我的文件中的数据是(在此测试的开头和结尾都添加了空格):
1 2 3
使用以下带有或不带有“std::ws”的代码加载数据不会造成任何差异。所以我对“std::ws”的作用感到困惑,因为我看到了使用它的代码。有人可以解释一下吗?谢谢!
void main ()
{
ifstream inf;
inf.open ("test.txt");
double x=0, y=0, z=0;
string line;
getline(inf, line);
istringstream iss(line);
//Using "std::ws" here does NOT cause any difference
if (!(iss >> std::ws >> x >> y >> z >> std::ws))
{
cout << "Format error in the line" << endl;
}
else
{
cout << x << y << z << endl;
}
iss.str(std::string ());
iss.clear();
cin.get();
}
Run Code Online (Sandbox Code Playgroud) 初始化std::stringstream 构造函数接受const string&以下参数:
explicit stringstream (const string& str,
ios_base::openmode which = ios_base::in | ios_base::out);
Run Code Online (Sandbox Code Playgroud)
这个接口在 C++98 中是合理的,但从 C++17 开始,我们有了std::string_view表示字符串的类的更便宜的替代方案。该类std::stringstream不会修改它接受的字符串,不拥有它,也不要求它以空终止。那么为什么不添加另一个接受 的构造函数重载呢std::string_view?是否存在任何障碍使该解决方案不可能(或不合理)屈服于Boost::Iostreams等替代方案?
c++ ×10
istringstream ×10
getline ×2
string ×2
stringstream ×2
c++17 ×1
clang++ ×1
compilation ×1
ifstream ×1
istream ×1
libc++ ×1
libstdc++ ×1
split ×1
stl ×1
string-view ×1
whitespace ×1