C ++:从文件读入并显示单个项目

时间:2018-03-19 21:39:35

标签: c++ file input fstream

所以我有一个.txt文件,我应该从一个整洁的小桌子里读取信息并显示。这是.txt文件内容的片段 格式为

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

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文件中出现两次,如果它是重复的,我应该将它们的数据合并为一行。对此的帮助也将受到赞赏。

感谢。

3 个答案:

答案 0 :(得分:2)

第一条建议:

不要使用

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

答案 1 :(得分:0)

我认为你应该尝试做更多的研究来理解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循环的下一次迭代。因此,您必须重新设计代码以保存服务器场中的先前值,并检查服务器场是否出现多次,并确定从那里开始执行操作。

答案 2 :(得分:0)

可以使用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;
}