首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么从std::istream读取记录结构字段失败,以及如何修复它?

为什么从std::istream读取记录结构字段失败,以及如何修复它?
EN

Stack Overflow用户
提问于 2014-04-14 03:00:56
回答 8查看 2.7K关注 0票数 19

假设我们有以下情况:

  • 按如下方式声明记录结构

struct Person { unsigned int id;std::string name;uint8_t age;// ... };

  • 记录使用以下格式存储在文件中:

ID名字姓年龄- 1267867约翰·史密斯32 67545无名氏36 8677453格温妮丝·米勒56 75543 J.罗斯不同寻常23 ...

应读取该文件以收集上述任意数量的Person记录:

代码语言:javascript
复制
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变量的字段中?

上面的code sample以运行时错误结束:

代码语言:javascript
复制
Runtime error    time: 0 memory: 3476 signal:-1
stderr: Input format error!
EN

回答 8

Stack Overflow用户

发布于 2014-04-14 03:03:01

名字和姓氏之间有空格。更改您的类,使名字和姓氏作为单独的字符串,它应该可以工作。您可以做的另一件事是读入两个独立的变量,如name1name2,并将其赋值为

代码语言:javascript
复制
actRecord.name = name1 + " " + name2;
票数 4
EN

Stack Overflow用户

发布于 2014-04-14 03:29:26

一个viable solution是重新排序输入字段(如果可能的话)

代码语言:javascript
复制
ID      Age Forename Lastname
1267867 32  John     Smith    
67545   36  Jane     Doe      
8677453 56  Gwyneth  Miller   
75543   23  J. Ross  Unusual  
...

并按如下方式读入记录

代码语言:javascript
复制
#include <iostream>
#include <vector>

struct Person {
    unsigned int id;
    std::string name;
    uint8_t age;
    // ...
};

int main() {
    std::istream& ifs = std::cin; // Open file alternatively
    std::vector<Person> persons;

    Person actRecord;
    unsigned int age;
    while(ifs >> actRecord.id >> age && 
          std::getline(ifs, actRecord.name)) {
        actRecord.age = uint8_t(age);
        persons.push_back(actRecord);
    }

    return 0;
}
票数 4
EN

Stack Overflow用户

发布于 2014-04-14 03:43:35

一种解决方案是将第一个条目读入ID变量。

然后读入行中的所有其他单词(只需将它们推入临时向量中),并使用所有元素构造个体的名称,最后一个条目是年龄。

这将允许您仍然在最后的位置上的年龄,但能够处理的名称,如"J.罗斯不同寻常“。

更新以添加一些说明上述理论的代码:

代码语言:javascript
复制
#include <memory>
#include <string>
#include <vector>
#include <iterator>
#include <fstream>
#include <sstream>
#include <iostream>

struct Person {
    unsigned int id;
    std::string name;
    int age;
};

int main()
{
    std::fstream ifs("in.txt");
    std::vector<Person> persons;

    std::string line;
    while (std::getline(ifs, line))
    {
        std::istringstream iss(line);

        // first: ID simply read it
        Person actRecord;
        iss >> actRecord.id;

        // next iteration: read in everything
        std::string temp;
        std::vector<std::string> tempvect;
        while(iss >> temp) {
            tempvect.push_back(temp);
        }

        // then: the name, let's join the vector in a way to not to get a trailing space
        // also taking care of people who do not have two names ...
        int LAST = 2;
        if(tempvect.size() < 2) // only the name and age are in there
        {
            LAST = 1;
        }
        std::ostringstream oss;
        std::copy(tempvect.begin(), tempvect.end() - LAST,
            std::ostream_iterator<std::string>(oss, " "));
        // the last element
        oss << *(tempvect.end() - LAST);
        actRecord.name = oss.str();

        // and the age
        actRecord.age = std::stoi( *(tempvect.end() - 1) );
        persons.push_back(actRecord);
    }

    for(std::vector<Person>::const_iterator it = persons.begin(); it != persons.end(); it++)
    {
        std::cout << it->id << ":" << it->name << ":" << it->age << std::endl;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23047052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档