gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 10:03:26 26 4
gpt4 key购买 nike

我有一个结构:

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/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com