C++;getline()';未记录的行为 在C++中,当使用 GETLILE()/在StrimeSnter上使用定界符时,很少有文件没有被发现,但在时它们有一些非错误的便利行为。 未找到分隔符=>然后返回整个字符串/其其余部分 有分隔符,但在它之前没有任何内容=>返回空字符串 获取不存在的内容=>返回最后可以读取的内容
一些测试代码(简化): 测试代码小提琴: 问题 问题是——这可以信赖吗?如果是,记录在哪里?是吗C++;getline()';未记录的行为 在C++中,当使用 GETLILE()/在StrimeSnter上使用定界符时,很少有文件没有被发现,但在时它们有一些非错误的便利行为。 未找到分隔符=>然后返回整个字符串/其其余部分 有分隔符,但在它之前没有任何内容=>返回空字符串 获取不存在的内容=>返回最后可以读取的内容,c++,stream,getline,stringstream,istringstream,C++,Stream,Getline,Stringstream,Istringstream,一些测试代码(简化): 测试代码小提琴: 问题 问题是——这可以信赖吗?如果是,记录在哪里?是吗 p> > < p>行为>代码> GETLION/CODE >在标准(C++ 11节21.4.8)7-10中被明确地记录,这是关于C++的唯一规范性文件。 您在前两个问题中询问的行为是有保证的,而第三个问题是您的测试设备是如何制作的 模板 基本流& getline(基本流和is, 基本字符串和str, 查特·德里姆); 模板 基本流& getline(基本信息流和信息流), 基本字符串和str,
<> p> > < p>行为>代码> GETLION/CODE >在标准(C++ 11节21.4.8)7-10中被明确地记录,这是关于C++的唯一规范性文件。 您在前两个问题中询问的行为是有保证的,而第三个问题是您的测试设备是如何制作的
模板
基本流&
getline(基本流和is,
基本字符串和str,
查特·德里姆);
模板
基本流&
getline(基本信息流和信息流),
基本字符串和str,
查特·德里姆);
效果:表现为未格式化输入函数(27.7.2.3),但不影响值
通过后续调用basic\u istream::gcount()
返回。在构造一个哨兵对象之后,
如果sentry
转换为true
,则调用str.erase()
,然后从is
中提取字符并追加
通过调用str.append(1,c)
直到出现以下任何一种情况时,将它们添加到str
:
- 文件结尾出现在输入序列上(在这种情况下,
getline
函数调用is.setstate(ios_base::eofbit)
)
traits::eq(c,delim)
用于下一个可用输入字符c
(在这种情况下,c
被提取,但
未附加)(27.5.5.4)
str.max\u size()
存储字符(在这种情况下,函数调用为.setstate(ios\u base::failbit
)(27.5.5.4)
按照所示顺序测试条件。在任何情况下,提取最后一个字符后
哨兵目标k
被摧毁
如果函数不提取任何字符,它将调用is.setstate(ios\u base::failbit)
,这可能会引发
ios_base::故障
(27.5.5.4)
返回:为
关于你的问题:
未找到分隔符=>然后返回整个字符串/其其余部分
这是第一个退出条件的结果-当输入字符串终止时,字符串流进入文件末尾,因此提取终止(在将所有前面的字符添加到输出字符串之后)
有分隔符,但在它之前没有任何内容=>返回空字符串
这只是第二点的一个特例-当找到分隔符时提取终止(traits::eq(c,delim)
通常归结为c==delim
),即使之前没有提取其他字符
获取不存在的内容=>返回最后可以读取的内容
事情不是这样的。如果流处于错误状态(在上面的描述中,sentry
对象未转换为true
)-在您的情况下,您有一个EOF-,getline
将保留字符串并返回。在测试代码中,你可以看到最后一个读数据,只是因为你在回收不同的测试之间的字符串,而不清除它。 < P> C++设备的行为是由ISO C++标准描述的。但是,它不是最具可读性的资源。在这种情况下,具有良好的覆盖率
下面是他们要说的。引用块被复制粘贴;我已经对你的问题作了解释
除了不受影响的input.gcount()。构造并检查哨兵对象后,执行以下操作:
“构造并检查哨兵”意味着如果在流中检测到错误条件,函数将返回而不做任何操作。这就是为什么在#3中,当“不应该有任何东西”时,观察最后一个有效输入
1) 调用str.erase()
因此,如果在分隔符之前没有找到任何内容,则将得到一个空字符串
2) 从输入中提取字符并将其附加到str,直到出现以下情况之一(按列出的顺序选中)
a) 输入时的文件结束条件,在这种情况下,getline设置eofbit
这是一种错误情况,导致字符串
局部变量被后续的getline
s更改
它还允许您观察输入结束前的最后一段,因此如果您愿意,可以将文件结尾视为分隔符
b) 下一个可用的输入字符是delim,由Traits::eq(c,delim)
测试,在这种情况下,分隔符字符从输入中提取,但不附加到str
c) str.max_size()字符已存储,在这种情况下,getline设置failbit并返回
3) 如果出于任何原因(甚至不是丢弃的分隔符)未提取任何字符,getline将设置failbit
并返回
你找到了什么文件?是的,所有的行为都完全在C++标准中被记录。它也被记录为大致相同。ok -第三-所以它构建了哨兵对象,它发现EOF,因此它转换为false,并且Sr.EraseEe()不被调用。(因此字符串保持不变)@jave.web:mostary-thesentry
对象也用于对流执行其他一些操作,bu
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
string test(const string &s, char delim, int parseIndex ){
stringstream ss(s);
string parsedStr = "";
for( int i = 0; i < (parseIndex+1); i++ ) getline(ss, parsedStr, delim);
return parsedStr;
}
int main() {
stringstream ss("something without delimiter");
string s1;
getline(ss,s1,';');
cout << "'" << s1 << "'" << endl; //no delim
cout << endl;
string s2 = "321;;123";
cout << "'" << test(s2,';',0) << "'" << endl; //classic
cout << "'" << test(s2,';',1) << "'" << endl; //nothing before
cout << "'" << test(s2,';',2) << "'" << endl; //no delim at the end
cout << "'" << test(s2,';',3) << "'" << endl; //this shouldn't be there
cout << endl;
return 0;
}
'something without delimiter'
'321'
''
'123'
'123'
template<class charT, class traits, class Allocator>
basic_istream<charT,traits>&
getline(basic_istream<charT,traits>& is,
basic_string<charT,traits,Allocator>& str,
charT delim);
template<class charT, class traits, class Allocator>
basic_istream<charT,traits>&
getline(basic_istream<charT,traits>&& is,
basic_string<charT,traits,Allocator>& str,
charT delim);