c++ - 读取文件以构造具有多种成员类型

标签 c++ struct

我有一个结构:

struct foo {
    int a;
    string b;
    bool c;
    //... ad infinitum
};

我想用 .txt 文件中的数据加载它,如下所示:
string a, b, c;
string* ptr[] = { &a, &b, &c };
ifstream file("input.txt");
size_t i = 0;
while (file >> *ptr[i])
    (i < 3) ? i++ : i = 0;
//convert a, c to int and bool, then assign

但是然后我将不得不手动将它们从字符串转换为 int 或 bool 类型,无论如何都可以加载所有它们而无需随后进行转换(也许使用 void* ptr[] )?
我不想这样:
while (!file.eof()){
  file>>a;
  file>>b;
  file>>c;
}

因为 Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong? ,我不想 file>> 10 次。

我也没有学习过 lexical_cast 或运算符重载之类的东西,因此任何与它们相关的答案都非常有帮助,但可能无法解决我的问题。

这是txt文件:
19127519
Jame Howard
0
19124567
Jacky Thomas
1
14527890
Lucas
1

最佳答案

您的解决方案中有几个问题

  • 当你想要 std::stringint 时,你只读取 bool
  • 您读取 std::string 的方式将任何空格视为分隔符,这意味着“Jame Howard”不是读入一个字符串而是两个分隔的,这不是您的代码在索引管理中假设的
  • 你(错误地)只保存了最后一个三元组而丢失了另一个

  • 当您打开文件时,请始终检查您是否能够做到。

    你可以这样做:
    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <string>
    
    struct foo {
      int a;
      std::string b;
      bool c;
      //... ad infinitum
    };
    
    int main()
    {
      std::ifstream file("input.txt");
    
      if (!file) 
        std::cerr << "cannot open input.txt" << std::endl;
      else {
        std::vector<foo> foos; // to save all struct
        foo f; // to read one struict
    
        while ((file >> f.a) &&
               file.ignore(std::numeric_limits<std::streamsize>::max(), '\n') && // flush rest of line
               std::getline(file, f.b) &&
               (file >> f.c))
          foos.push_back(f);
    
        // check
        for (auto f : foos)
          std::cout << f.a << ' ' << f.b << ' ' << f.c << std::endl;
      }
    }
    

    字符串可以包含空格,因此不可能在 f 是 foo 的情况下执行 file >> f.b,可以使用 getline,但由于每个元素都在单独的行中,因此有必要在读取 int 后刷新行尾。

    编译和执行:
    pi@raspberrypi:~ $ g++ -g -Wall f.cc
    pi@raspberrypi:~ $ cat input.txt 
    19127519
    Jame Howard
    0
    19124567
    Jacky Thomas
    1
    14527890
    Lucas
    1
    pi@raspberrypi:~ $ ./a.out
    19127519 Jame Howard 0
    19124567 Jacky Thomas 1
    14527890 Lucas 1
    pi@raspberrypi:~ $ 
    

    与其将代码放在 main 中读取 foo ,不如定义 operator >> (如果需要 operator << )更自然,所以:
    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <limits>
    
    struct foo {
      int a;
      std::string b;
      bool c;
      //... ad infinitum
    };
    
    std::istream& operator >>(std::istream & in, foo & f) {
      if ((in >> f.a) &&
          in.ignore(std::numeric_limits<std::streamsize>::max(), '\n') && // flush rest of line
          std::getline(in, f.b))
        in >> f.c;
      return in;
    }
    
    int main()
    {
      std::ifstream file("input.txt");
    
      if (!file) 
        std::cerr << "cannot open input.txt" << std::endl;
      else {
        std::vector<foo> foos;
        foo f;
    
        while (file >> f)
          foos.push_back(f);
    
        for (auto f : foos)
          std::cout << f.a << ' ' << f.b << ' ' << f.c << std::endl;
      }
    }
    

    如果 foo 具有私有(private)属性 operator << 必须在 foo 中声明 friend

    关于c++ - 读取文件以构造具有多种成员类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61427463/

    相关文章:

    c++ - VTK VisualStudio2013编译错误

    C++ 从 vector <algorithm> 和 <functional> 中删除字符串

    c++ - 为 vector<string> 预留更大容量后发生段错误

    c++ - 制作 boost http 客户端

    c++ - 使用 std::vector::iterator 更改存储在 std::vector 中的值?

    c - 如何通过 xmlrpc-c 传递哈希表之类的对象?

    c++ - 逗号分隔的流到结构中

    c - 如何将结构中的多个 void 指针取消引用到 1 block 内存中?

    c - 我如何检查另一个结构中的结构是否为空?

    c - struct 的成员正在被修改,但为什么呢?