为什么从std :: istream读取记录结构字段失败,我如何解决它? [英] Why does reading a record struct fields from std::istream fail, and how can I fix it?
问题描述
假设我们有以下情况:
- 记录结构声明如下
struct Person {
unsigned int id;
std::string name;
uint8_t age;
// ...
};
- 记录使用以下格式存储在文件中:
ID Forename Lastname Age
------------------------------
1267867 John Smith 32
67545 Jane Doe 36
8677453 Gwyneth Miller 56
75543 J. Ross Unusual 23
...
应该被读入以收集任意数量的上述<$ p $ c> Person 记录:
The file should be read in to collect an arbitrary number of the Person
records mentioned above:
std::istream& ifs = std::ifstream("SampleInput.txt");
std::vector<Person> persons;
Person actRecord;
while(ifs >> actRecord.id >> actRecord.name >> actRecord.age) {
persons.push_back(actRecord);
}
if(!ifs) {
std::err << "Input format error!" << std::endl;
}
(这是一个常见问题,以一种或另一种形式)
我可以做什么来读取单独的值,将它们的值存储到一个 actRecord
variables'字段?
Question: (that's a frequently asked question, in the one or the other form)
What can I do to read in the separate values storing their values into the one actRecord
variables' fields?
上述代码示例最后出现运行时错误:
The above code sample ends up with run time errors:
Runtime error time: 0 memory: 3476 signal:-1
stderr: Input format error!
推荐答案
的一个操纵器我想出了计数分隔符通过每个提取的字符。使用您指定的分隔符数,它将从输入流中提取单词。这是一个工作演示。
Here's an implementation of a manipulator I came up with that counts the delimiter through each extracted character. Using the number of delimiters you specify, it will extract words from the input stream. Here's a working demo.
template<class charT>
struct word_inserter_impl {
word_inserter_impl(std::size_t words, std::basic_string<charT>& str, charT delim)
: str_(str)
, delim_(delim)
, words_(words)
{ }
friend std::basic_istream<charT>&
operator>>(std::basic_istream<charT>& is, const word_inserter_impl<charT>& wi) {
typename std::basic_istream<charT>::sentry ok(is);
if (ok) {
std::istreambuf_iterator<charT> it(is), end;
std::back_insert_iterator<std::string> dest(wi.str_);
while (it != end && wi.words_) {
if (*it == wi.delim_ && --wi.words_ == 0) {
break;
}
dest++ = *it++;
}
}
return is;
}
private:
std::basic_string<charT>& str_;
charT delim_;
mutable std::size_t words_;
};
template<class charT=char>
word_inserter_impl<charT> word_inserter(std::size_t words, std::basic_string<charT>& str, charT delim = charT(' ')) {
return word_inserter_impl<charT>(words, str, delim);
}
现在你可以这样做:
while (ifs >> actRecord.id >> word_inserter(2, actRecord.name) >> actRecord.age) {
std::cout << actRecord.id << " " << actRecord.name << " " << actRecord.age << '\n';
}
这篇关于为什么从std :: istream读取记录结构字段失败,我如何解决它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!