尝试将.csv文件加载到std::vector中< struct>

zpqajqem  于 2024-01-03  发布在  其他
关注(0)|答案(1)|浏览(109)

我正在尝试编写一个函数来将.csv文件加载到vector<item>中:

std::vector<Item> LoadDataFromFileStruct(std::string filePath)
{
    
    std::fstream fileCon;
    fileCon.open(filePath);
    std::vector<Item> items{};
    
    while (fileCon.peek() != EOF) {
        Item item{};
        while (fileCon.peek() != '\n')
        {
            std::getline(fileCon, item.marca, ',');
            std::getline(fileCon, item.modelo, ',');
            std::getline(fileCon, item.cv, ',');
            std::getline(fileCon, item.m2h, ',');
            std::getline(fileCon, item.preço, '\n');

        }
        items.push_back(item);
    }
    fileCon.close();

    return items;
}

字符串
我遇到的问题是,当编译器到达第6行(std::vector<Item> items{};)时,它跳到return items;行,我使用Visual Studio调试工具检查了这一点。
程序编译。
此外,我意识到它会卡在内部while循环中。
我对编程很陌生,所以可能是简单的东西。
我还编写了下面的代码,以便将数据从.csv文件加载到vector<vector<string>>中,它可以正常工作而不会出现此问题。

std::vector<std::vector<std::string>> LoadDataFromFile(std::string filePath)
{
    //Vars
    std::ifstream fileCon;
    fileCon.open(filePath);
    std::vector<std::vector<std::string>> loadedData;
    //Iterator
    if (!fileCon.is_open()) {
        std::cout << "Unable to open files";
        return std::vector<std::vector<std::string>>{};
    }
    while (fileCon.peek() != EOF) {
        std::vector<std::string> row;
        std::string celStr{ 0 };
        while (fileCon.peek()!='\n')
        {
            std::getline(fileCon, celStr,',');
            row.push_back(celStr);
            if (celStr.back()=='\n')
            {
                break;
            }
        }
        loadedData.push_back(row);
    }
    fileCon.close();
    return loadedData;
}


我真的不知道下一步该怎么做,我怀疑使用vector结构体对象是个坏主意。

yzuktlbb

yzuktlbb1#

我遇到的问题是,当编译器到达第6行(std::vector<Item> items{};)时,它跳到return items;行,我使用Visual Studio调试工具检查了这一点。
我能看到发生这种情况的唯一方法是如果fileCon.peek()立即返回EOF,即如果文件没有成功打开,你在第一个例子中没有检查(但你在第二个例子中)。
也就是说,在这两个例子中都没有使用peek()的充分理由。通过使用std::getline()逐行阅读文件并使用std::istringstream解析每行,可以使这两个例子变得更简单,例如:

std::vector<Item> LoadDataFromFileStruct(std::string filePath)
{
    std::ifstream fileCon(filePath);
    std::vector<Item> items;
    
    if (!fileCon.is_open()) {
        std::cout << "Unable to open file\n";
        return items;
    }

    std::string line;
    while (std:getline(fileCon, line)) {
        std::istringstream iss(line);
        Item item;

        std::getline(iss, item.marca, ',');
        std::getline(iss, item.modelo, ',');
        std::getline(iss, item.cv, ',');
        std::getline(iss, item.m2h, ',');
        std::getline(iss, item.preço);

        items.push_back(item);
    }

    return items;
}

个字符
在第一个例子中,我甚至建议更进一步,为Item定义一个operator>>,然后你可以简单地使用while (fileCon >> item),例如:

std::istream& operator>>(std::istream &input, Item &item)
{
    std::string line;
    if (std:getline(input, line)) {
        std::istringstream iss(line);

        std::getline(iss, item.marca, ',');
        std::getline(iss, item.modelo, ',');
        std::getline(iss, item.cv, ',');
        std::getline(iss, item.m2h, ',');
        std::getline(iss, item.preço);

        if (iss.fail()) {
            input.setstate(std::ios_base::failbit);
        }
    }

    return input;
}

std::vector<Item> LoadDataFromFileStruct(std::string filePath)
{
    std::ifstream fileCon(filePath);
    std::vector<Item> items;
    
    if (!fileCon.is_open()) {
        std::cout << "Unable to open file\n";
        return items;
    }

    Item item;
    while (fileCon >> item) {
        items.push_back(item);
    }

    return items;
}


或者,甚至使用std::istream_iterator构造返回的vector,例如:

std::vector<Item> LoadDataFromFileStruct(std::string filePath)
{
    std::ifstream fileCon(filePath);
    
    if (!fileCon.is_open()) {
        std::cout << "Unable to open file\n";
        return std::vector<Item>{};
    }

    return std::vector<Item>{
        std::istream_iterator<Item>(fileCon),
        std::istream_iterator<Item>{}
    };

    // or simply:
    // return {std::istream_iterator<Item>(fileCon), {}};
}

相关问题