【问题标题】:C++: Reading in from a file and displaying individual itemsC ++:从文件中读取并显示单个项目
【发布时间】:2018-03-19 21:39:34
【问题描述】:

所以我有一个 .txt 文件,我应该从中读取信息并显示在一个整洁的小表格中。这是 .txt 文件内容的 sn-p 格式

农场名称、商品数量、商品、价格、总价

Collins Farm, 43900 tomatoes 0.67 29413
Bart Smith Farms, 34910 cassavas 0.99 34560.9
Allen Farms, 117 coconuts 0.54 63.18

等等……

它应该在控制台中打印为

柯林斯农场(此处有一些空间)43900 件商品共贡献了 29413.00 美元

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;
int addLine(int);

int main()
{
using std::ifstream;

ifstream myFile;
myFile.open("ASSGN6-B.txt");

string farmName;
int itemCount;
string itemName;
double itemPrice;
double totalPrice;

if (!myFile)
{
    cout << "File open failed!" << endl;
}
else
{
    cout << "\t\t\t=========================================================" << endl;
    cout << "\t\t\t=               FARMER'S MARKET INVENTORY               =" << endl;
    cout << "\t\t\t=========================================================" << endl;

    while (myFile.good())
    {
        getline (myFile, farmName);
        getline (myFile, itemName);
        myFile >> itemName >> itemPrice >> totalPrice;
        cout << farmName << "       " << itemCount << " items contributed totaling $" << totalPrice << endl;

    }
}


myFile.close();
return 0;
}

这就是我一直在搞砸的,试图弄清楚这个输入的东西是如何工作的。我想我真正不明白的是它应该如何知道哪个项目是哪个。我以前认为它只是一次读取一行,但必须有一种方法可以将同一行中的项目分开并在控制台中单独打印。

此外,一些农场名称在 .txt 文件中出现两次,如果重复,我应该将它们的数据合并到一行中。对此的帮助也将不胜感激。

谢谢。

【问题讨论】:

  • 我强烈建议在互联网上搜索“StackOverflow C++ 读取文件 csv”。这将列出许多示例供您学习。

标签: c++ file input fstream


【解决方案1】:

第一条建议:

不要使用

while (myFile.good()) { ... }

您需要确保您希望读取的数据确实被成功读取。

请参阅Why is iostream::eof inside a loop condition considered wrong? 了解原因。

解决其他问题...

线

    getline (myFile, farmName);

将整行读入farmName。那不是你想要的。您想要阅读直到逗号 (,) 字符的所有内容。 std::getline 有这样的选择。使用

    getline (myFile, farmName, ',');

不清楚你希望通过什么来完成

    getline (myFile, itemName);

该行可以删除。

查看示例数据,您所需要的只是

    myFile >> itemCount >> itemName >> itemPrice >> totalPrice;

读取其余数据。

但是,在您阅读它们之后,请确保忽略该行中的所有内容。你可以使用istream::ignore

这是我的建议。

while ( getline(myFile, farmName, ',') &&
       (myFile >> itemCount >> itemName >> itemPrice >> totalPrice) )
{
    cout << farmName << "       " << itemCount << " items contributed totaling $" << totalPrice << endl;

    // Ignore rest of the line
    myFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

请务必添加

#include <limits>

能够使用std::numeric_limits

【讨论】:

    【解决方案2】:

    我认为你应该尝试做更多的研究来理解 c++ 中的文件操作,但我注意到你的代码有一些事情:

    getline(myFile, farmName);
    

    这一行将读取它正在读取的文件的整行并将其存储到farmName中。它基本上读取该行,直到找到行尾字符。我认为您的意图是让该行一直读取到农场名称的逗号,因此您将使用:

    getline(myFile, farmName, ',');
    

    第三个参数是一个可选的分隔符,它告诉 getline 查找哪个字符以停止读取。

    我注意到的下一行是:

    getline(myFile, itemName);
    myFile >> itemName >> itemPrice >> totalPrice;
    

    为什么要两次将数据读入 itemName?我认为你的意思是从你的文件格式的外观来看,在 itemName 之前先读入 itemCount,因此你应该删除上面显示的第一行,只需要:

    myFile >> itemCount >> itemName >> itemPrice >> totalPrice;
    

    如果农场名称出现不止一次,就添加到现有数据而言,您当前的代码会在打印后覆盖每一行的数据并继续进行 while 循环的下一次迭代。因此,您将不得不重新设计您的代码以保存来自农场的先前值,并检查农场是否多次出现并确定从那里做什么。

    【讨论】:

    • 谢谢。我根据线程中其他人的建议更新了我的代码,它现在按预期工作。至于重新设计结构以允许组合数据,您能否引导我朝着正确的方向前进?
    • @Cartino 我不确定你的任务是什么,但你可以创建一个类来表示一个“农场项目”,并为它提供农场名称、项目名称、项目价格和项目的属性数数。然后,您可以创建一个数组或向量来保存许多农场项目,并在该农场项目数组/向量中添加一个新的农场项目(如果它尚不存在)。无需在读取每个农场项目的数据后立即打印,而是可以等到填充完数组/向量,然后在关闭文件后打印收集的所有内容。
    • @Cartino 我没有说为总价添加属性的原因是因为它是从 (item count) * (item price) 派生的值,因此最好是返回这两个值相乘的方法。因此,您将有一个方法返回一个名为 getTotalPrice() 的方法,而不是总价格的变量成员。
    【解决方案3】:

    可以使用regex:

    std::string line;
    std::regex r{R"(([^,]*), ?([^ ]*) ([^ ]*) ([^ ]*) (\d*.?\d*))"};
    std::smatch m;
    while(getline(myFile, line)){
        std::regex_match(line, m, r);
    
        std::string farmName    {          m[1] };
        int itemCount           {std::stoi(m[2])};
        std::string itemName    {          m[3] }; 
        double itemPrice        {std::stod(m[4])};
        double totalPrice       {std::stod(m[5])};
    
        std::cout << farmName << "       " << itemCount << " items contributed totaling $" << totalPrice << std::endl;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2013-07-09
      • 1970-01-01
      • 2011-09-29
      相关资源
      最近更新 更多