c++ - 了解如何读入文件并将文件中的行分隔为不同的变量

标签 c++ file-io ifstream

这就是我的困境。我今天要交这个家庭作业,它涉及从文件中读取数据,将行分成不同的变量,并根据某些参数显示行。我(以及我的同学)遇到的问题是我们的教授在教学方面非常糟糕,而且我们的投影仪目前坏了,她无法根据预先给定的幻灯片进行教学,而是 100% 依赖于她想出的例子并且解释得很少。不仅如此,而且我已经为此工作了几个小时,现在是早上 4:30,无论教授如何,我的编程都非常糟糕。我从来都不是很好,它实际上会让我改变专业,因为我无法掌握它。基本上,我只需要了解朝着正确的方向采取的步骤,否则我将整夜不眠,并因此而在一天中度过一个痛苦的休息时间。

我们的任务涉及从农场列表中获取数据,其中还包括一些元素、所述元素的描述、每件元素的价格以及所述元素的总成本乘以每件元素的成本,所有这些都在一行中“完整”列表。如果农场本身已经在文件中之前提到过(重复项可以方便地并排放置),则将项目数量和总价添加到一行中。因此,例如,“Big Top Farm”的 3 个列表之间将显示为一行,其中包含 10,625 个总项目,总成本为 5,622.30 美元。最后,该代码旨在打印出特定数量的贡献的“独特”农场(具有重复条目的农场仅包含一次)。我知道我可以用一个简单的计数器整数和一个快速的++ 序列来解决这个问题,但这是我唯一知道我做对的事情。

这是我对代码的绝望尝试(是的,我知道它未完成且未构建)

#include <fstream>
#include <cstdlib>
#include <string.h>

using std::cin;
using std::cout;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::ios;
using std::string;

//prototypes
void readIn();
int farmDisplay(int, string, double, double);


int main()
{
    string farmName, itemType;
    int itemCount, farms;
    double itemPrice, totalPrice;


    cout << "==================================================" << endl;
    cout << "=           FARMER'S MARKET INVENTORY            =" << endl;
    cout << "==================================================" << endl;

    farms = farmDisplay(itemCount, itemType, itemPrice, totalPrice);

    cout << endl;
    cout << "There were " << farms << " unique farms contributing to this week's event." << endl;

    return 0;
}

//precondition:
//postcondition:
int farmDisplay(int itemCount, string itemType, double itemPrice, double totalPrice)
{
    int counter = 0, result, prevItemCount, currentItemCount;
    string farmName, prevFarm, currentFarm;
    ifstream inFile;

    inFile.open("ASSGN6-B.txt");

    //Check for Error
    if(inFile.fail())
    {
        cout << "Error opening file..." << endl;
        exit(1);
    }

    while(!inFile.eof())
    {
        cin.ignore();

        getline(inFile, currentFarm, ',');


        if(prevFarm.compare(currentFarm) == 0)
        {
            prevFarm = currentFarm;
            prevItemCount == currentItemCount;

            counter--;
        }
        else
        {
            prevFarm = currentFarm;
            prevItemCount == currentItemCount;
        }

        inFile >> itemCount >> itemType >> itemPrice >> totalPrice;

        cout << farmName << "     " << itemCount << " items contributed totaling $" << totalPrice << endl;

        counter++;
    }
    inFile.close();

    return counter;
}

这是我们得到的文件的样子:

Collins Farm, 43900 tomatoes 0.67 29413
Bart Smith Farms, 34910 cassavas 0.99 34560.9
Allen Farms, 117 coconuts 0.54 63.18
River Run Farm, 103 taros 0.65 66.95
Big Top Farm, 109 artichokes 2.23 243.07
Big Top Farm, 777 crosns 0.28 217.56
Big Top Farm, 9739 cucumbers 0.53 5161.67
Marble Farm, 108 crosns 0.33 35.64
Food For Life Inc., 106 carrots 0.87 92.22
Food For Life Inc., 86 coconuts 0.84 72.24
Johnson Farms, 121 parsnips 0.22 26.62
A1 Farm, 111 beets 0.12 13.32
A1 Farm, 5591 taros 0.72 4025.52
Looney Tunes Farm, 102 onions 0.49 49.98
Wolfe Creek Farm, 103 rhubarbs 1.21 124.63
Wolfe Creek Farm, 199 radishes 0.71 141.29
James Farm, 47 pickles 0.68 31.96
Weaver Farms, 75 walnuts 2.5 187.5
Weaver Farms, 500 pickles 0.59 295
Pore Boy Farms, 670000 peanuts 0.79 529300
Rutherford Farms Inc., 809 apples 0.9 728.1
Rutherford Farms Inc., 659 pickles 0.7 461.3
Javens Farm, 129000 figs 0.44 56760
Harrison Farms, 8001 yams 1.09 8721.09
Setzer Farms Inc., 701 potatoes 0.89 623.89
Setzer Farms Inc., 651 tomatoes 0.69 449.19
Pikes Peak Farm, 1045 turnips 0.79 825.55
Holland Area Farms, 10001 radishes 0.69 6900.69

任何建议都将不胜感激,因为我觉得我会再疯狂地从事这个项目

最佳答案

好的,我将为您提供一般方法和一些基本想法。首先,编码并不容易。这就是为什么我们这些老程序员过着非常美好的生活。但你不会只是游弋其中。这需要奉献精神和好奇心。您必须喜欢它,但考虑编写一个巨大的难题。

现在,当您对一项任务感到不知所措时,请将其分解成更小的部分。你真的有点把它变成了一大块。

这是我会做的。我会创建一个类来表示原始数据。我会创建一个类来加载文件,然后我会编写一个方法来分析数据并将其输出。

在这种情况下,从类开始。

// This holds one line's data
class LineItem {
public:
    std::string farmName;
    std::string itemName;
    int quantitySold;
    double priceEach;
    double totalPrice;

    // You'll need to implement this, see comments below.
    LineItem(const std::string fromString);
};

// This holds all the data for a specific farm.
class Farm {
public:
    std::string name;
    std::vector<LineItem *> lineItems;
};

// And this holds all the farms with the key being the farm name.
std::map<std::string, Farm *> allfarmsByName;

此时,你需要一个读取数据的方法。我会阅读每一行,然后在分隔符(逗号和/或空格)处拆分字符串。第一列是名称,第二列是数量等。

这是一段您应该能够编写的相对简单的代码。所以你可以获得数据行,然后做这样的事情:

 LineItem *newItem = new LineItem(myString);

如果您实现了该构造函数,那么您可以这样做:

 Farm * farm = allFarmsByName[newItem->farmName];
 if (farm == nullptr) {
     farm = new Farm();
     farm->name = newItem->farmName;
     allFarmsByName.insert(pair<std::string, Farm *>(farm->name, farm)); 
 }

此时,您的 allFarmsByName 类为每个贡献农场提供一个项目,并且每个农场都有一个包含所有数据的 vector 。

因此,要打印本月帮助了多少农场,您只需要打印 allFarmsByName 的大小即可。

现在,具体如何操作并不重要。这是方法。分解它。

  1. 首先,设想您的数据并构建类来表示数据。
  2. 其次,将文件中的数据读入这些对象。
  3. 然后做您需要做的任何事情来执行分析。

这是一种工作模式。设想数据。读取数据。报告数据。

关于c++ - 了解如何读入文件并将文件中的行分隔为不同的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58587689/

相关文章:

c++ - 我可以从 ifstream/ofstream 获取使用的文件名吗?

java - 在 Java 中使用 Zip 和 GZip 文件

python - 通过文件读/写与Python代码交互?

c++ - 如何只读取文件.txt 中的数字?

c++ - ifstream 无法打开

c++ - 如何提高C++中merkle根的计算速度?

c++ - 如何修复编译错误 : non-template 'iterator1' used as template

windows - 为所有用户存储具有读\写权限的应用程序数据的最佳目录?

C++ 从文件中读/写 N 个字节(甚至是 '00' 字节)

c++ - 为什么我需要时间来关闭流程中的文件