C ++数据文件,数组和计算分配

时间:2018-10-30 03:08:56

标签: c++ arrays file

我是C ++的新手,在我的一项作业中遇到问题。目的是从看起来像这样的数据文件中加载数据。

item number date    quantity    cost per each
1000       6/1/2018    2            2.18
1001       6/2/2018    3            4.44
1002       6/3/2018    1            15.37
1001       6/4/2018    1            4.18
1003       6/5/2018    7            25.2

基本上,我需要使用数组来计算每个日期使用的平均物品编号,并使用成本进行其他一些计算。我真的很想从文件中加载数据并对其进行方程式处理。这就是我到目前为止所拥有的。

#include <cmath> //for math operations
#include <iostream> //for cout
#include <cstdlib> //for compatibility
#include <fstream>
#include <string>
using namespace std;

int main() 
{   
string date;
int EOQ, rp;
int count;
int itemnum[][];
double quantity[][];
double cost[][];
ifstream myfile; 
string filename;
cout << "Data File: " << endl;
cin >> filename; // user enters filename

myfile.open(filename.c_str());

if(myfile.is_open())
{
    cout << "file opened" << endl;
    string head;
    while(getline(myfile, head))
    {
    break; // so header won't interfere with data
    }
while(!myfile.eof())
{ // do this until reaching the end of file

int x,y;

myfile >> itemnum[x][y] >> date >> quantity[x][y] >> cost[x][y];


cout << "The numbers are:" << endl;
for(count = 0; count < y; count++)
{
cout << itemnum[x][y] << endl; 
break;
}

//cout << "Item:         Reorder Point:       EOQ: " << endl;
//cout << itemnum << "      " << rp << "          " << EOQ << endl;

break;
}
}
else
{
    cout << "" << endl; //in case of user error
    cerr << "FILE NOT FOUND" << endl;
}


cout << endl;
cout << "---------------------------------------------" << endl;
cout << "   End of Assignment A8" << endl;
cout << "---------------------------------------------" << endl;
cout << endl;

system("pause");
return 0;

由于我仍然无法将文件加载到简单数组中,因此我还没有开始处理方程式!!

谢谢!

数据文件链接:https://drive.google.com/file/d/1QtAC1bu518PEnk4rXyIXFZw3AYD6OBAv/view?usp=sharing

1 个答案:

答案 0 :(得分:0)

在处理这类问题时,我喜欢将其分解为与解析相关的部分。我正在使用一些标准库为我做一些工作。我还创建了两个结构来帮助保持数据信息的组织性。至于您的日期,我可以将其保留为一个std::string,但我选择将date本身分解为三种类型,并将它们存储在数据结构中,以显示其中一种功能。解析所涉及的功能。

我更喜欢做的是从文件中获取一行数据并将其保存到字符串中,或​​者获取文件的全部内容并将其保存到大缓冲区或字符串向量中,除非我正在处理不适用的特定类型的代码,例如解析wav文件。当我读完文件后,再合上文件的手!然后,在获得所需的所有信息之后,与其尝试在打开文件时不尝试直接解析文件,不如解析一个字符串,因为它更易于解析。然后,在解析字符串之后,我们可以填充所需的数据类型。

我必须稍微修改您的数据文件以容纳额外的空白,因此我将文件另存为文本文件,在一行文本中每种数据类型之间只有一个空白。我也没有包括第一行(标题)信息,因为我完全省略了它。但是,这仍应作为如何为具有良好可读性,可重用性的应用程序设计良好工作流程的指南,并尝试使其保持可移植性并尽可能通用。现在,您一直在等待什么;我的代码版本的演示:


#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <exception>

struct Date {
    int month;
    int day;
    int year;

    Date() = default;
    Date( int monthIn, int dayIn, int yearIn ) :
        month( monthIn ),
        day( dayIn ),
        year( yearIn ) 
    {}
};

struct DataSheetItem {
    int itemNumber;
    Date date;
    int quantity;
    double costPerEach;

    DataSheetItem() = default;
    DataSheetItem( int itemNumberIn, Date& dateIn, int quantityIn, double costPerEachIn ) :
        itemNumber( itemNumberIn ),
        date( dateIn ),
        quantity( quantityIn ),
        costPerEach( costPerEachIn ) 
    {}
};

std::vector<std::string> splitString( const std::string& s, char delimiter ) {
    std::vector<std::string> tokens;
    std::string token;
    std::istringstream tokenStream( s );
    while( std::getline( tokenStream, token, delimiter ) ) {
        tokens.push_back( token );
    }

    return tokens;
}

void getDataFromFile( const char* filename, std::vector<std::string>& output ) {
    std::ifstream file( filename );
    if( !file ) {
        std::stringstream stream;
        stream << "failed to open file " << filename << '\n';
        throw std::runtime_error( stream.str() );
    }

    std::string line;

    while( std::getline( file, line ) ) {
        if ( line.size() > 0 ) 
            output.push_back( line );
    }
    file.close();
}

DataSheetItem parseDataSheet( std::string& line ) {    
    std::vector<std::string> tokens = splitString( line, ' ' ); // First parse with delimeter of a " "

    int itemNumber = std::stoi( tokens[0] );
    std::vector<std::string> dateInfo = splitString( tokens[1], '/' );
    int month = std::stoi( dateInfo[0] );
    int day   = std::stoi( dateInfo[1] );
    int year  = std::stoi( dateInfo[2] );
    Date date( month, day, year );
    int quantity = std::stoi( tokens[2] );
    double cost = std::stod( tokens[3] );

    return DataSheetItem( itemNumber, date, quantity, cost );
}

void generateDataSheets( std::vector<std::string>& lines, std::vector<DataSheetItem>& dataSheets ) {
    for( auto& l : lines ) {
        dataSheets.push_back( parseDataSheet( l ) );
    }
}

int main() {
    try {
        std::vector<std::string> fileConents;
        getDataSheetItemsFromFile( "test.txt", fileContents );
        std::vector<DataSheetItem> data;
        generateDataSheets( fileConents, data );

        // test to see if info is correct
        for( auto& d : data ) {
            std::cout << "Item #: " << d.itemNumber << " Date: "
                << d.date.month << "/" << d.date.day << "/" << d.date.year
                << " Quantity: " << d.quantity << " Cost: " << d.costPerEach << '\n';
        }

    } catch( const std::runtime_error& e ) {
        std::cerr << e.what() << '\n';
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

注意:这不适用于您当前的文件状态;这不考虑文本的第一行(标题信息),也不考虑数据字段之间的任何额外空白。如果在打开文件时添加一行文本并读入一行而忽略它,则执行循环以使所有字符串添加到矢量中以返回;您的向量将包含其中的信息,但是由于所有额外的空白,它们将不在向量的正确索引位置。这是您需要注意的事情!除此之外;这就是我基本上将设计一个程序或应用程序以解析数据的方式。绝对不是100%完整的证明,甚至可能不是100%的错误,但是快速浏览并通过我的调试器运行了好几次,它似乎没有任何明显的错误。在运行时效率方面还可能有一些改进的空间,等等。但这只是基本解析的概括。