istream_iterator尝试解析无效数据
您好,我希望有人能帮助理解以下代码的这种行为。
#include <iostream>
#include <algorithm>
#include <string>
#include <limits>
#include <fstream>
#include <iterator>
#include <stdexcept>
struct asound_stanza
{
unsigned index;
std::string name;
friend std::istream &operator>>(std::istream &is, asound_stanza &stan)
{
is >> stan.index;
if(!is.good())
return is;
std::getline(is, stan.name);
std::string::const_iterator
eol = stan.name.cend(),
start = std::find(stan.name.cbegin(), eol, '['),
end = std::find(start, eol, ' ');
stan.name = std::string(++start, end);
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// std::istream_iterator<char> it;
// while(*it++!=0x0a);
return is;
}
};
int main()
{
std::ifstream is("/proc/asound/cards", std::ifstream::in);
std::istream_iterator<asound_stanza> it(is), end;
unsigned devid = 0;
std::for_each(it, end, [&](const asound_stanza &stan)->void{
if(stan.name!="CODEC")
return;
devid = stan.index;
});
std::cout << devid;
return 0;
}
这有效,但我有几个问题。完成所有有效的迭代后,它会继续尝试解析另一个迭代,但不可避免地会失败(因此出现 if(!is.good())...
_)。它尝试解析它,但它永远不会将最终的格式错误的结构传递到 lambda 表达式。为什么不呢?是因为流不好()所以它不费心尝试将其传递进去吗?
另外,我怎样才能让它不去尝试解析最终的结构,(每个节以换行符(0x0a)结尾,所以我认为忽略流直到换行符会导致最终有效迭代中的 EOF 并非如此。
但事实
也请随意传递另一个编码正确性评论:
我的文件看起来像这样。
0 [Intel ]: HDA-Intel - HDA Intel
HDA Intel at 0xfc500000 irq 46
1 [HDMI ]: HDA-Intel - HDA ATI HDMI
HDA ATI HDMI at 0xfc010000 irq 47
2 [CODEC ]: USB-Audio - USB Audio CODEC
Burr-Brown from TI USB Audio CODEC at usb-0000:00:1d.7-3.1, full speed
Hi was I hoping someone would help understand this behaviour of the below code.
#include <iostream>
#include <algorithm>
#include <string>
#include <limits>
#include <fstream>
#include <iterator>
#include <stdexcept>
struct asound_stanza
{
unsigned index;
std::string name;
friend std::istream &operator>>(std::istream &is, asound_stanza &stan)
{
is >> stan.index;
if(!is.good())
return is;
std::getline(is, stan.name);
std::string::const_iterator
eol = stan.name.cend(),
start = std::find(stan.name.cbegin(), eol, '['),
end = std::find(start, eol, ' ');
stan.name = std::string(++start, end);
is.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// std::istream_iterator<char> it;
// while(*it++!=0x0a);
return is;
}
};
int main()
{
std::ifstream is("/proc/asound/cards", std::ifstream::in);
std::istream_iterator<asound_stanza> it(is), end;
unsigned devid = 0;
std::for_each(it, end, [&](const asound_stanza &stan)->void{
if(stan.name!="CODEC")
return;
devid = stan.index;
});
std::cout << devid;
return 0;
}
this works, but I have a few questions. after all the valid iterations are done it goes a head and tries to parse another one which inevitably fails (hence the if(!is.good())...
_). It tries to parse it but it never passes the final malformed struct onto the lambda expression. Why doesn't it? Is it because the streams is not good() so it doesn't bother trying to pass it in?
Also how can I get it to not even bother try and parse the final struct, (each stanza ends with a newline (0x0a), So I would have thought that ignoring the stream up until the newline would cause an EOF on the final valid iteration but it doesn't.
Thanks for your guidance.
Also feel free to pass on another coding correctness comments.
PS: my file looks like this
0 [Intel ]: HDA-Intel - HDA Intel
HDA Intel at 0xfc500000 irq 46
1 [HDMI ]: HDA-Intel - HDA ATI HDMI
HDA ATI HDMI at 0xfc010000 irq 47
2 [CODEC ]: USB-Audio - USB Audio CODEC
Burr-Brown from TI USB Audio CODEC at usb-0000:00:1d.7-3.1, full speed
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果流处于无效状态或者尝试从操作符内部的流读取>>>失败并将流设置为无效状态,istream_iterator 将自身设置为流位置的末尾。因此迭代结束时甚至没有查看部分解析的对象。
If stream is in invalid state or if attempt to read from stream inside operator>> fails and sets stream to invalid state, istream_iterator sets itself to end of stream position. So iteration ends without even looking at partially parsed object.
您的代码应如下所示:
阅读我上面修改中的注释!
由于这个问题已经讨论过很多次了,我也已经回答过很多次了,所以我不想再重复了。请阅读我的其他答案,它解释了这一点:
Your code should look like this:
Read the comments in my modification above!
Since this has been discussed so many times, and I've answered many times before, that I don't want to repeat it again. Please read my other answer which explains the very thing: