C ++数据文件,数组和计算分配 [英] C++ Data files, arrays, and calculations assignment

查看:120
本文介绍了C ++数据文件,数组和计算分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to C++ and I'm running into an issue on one of my assignments. The goal is to load data from a data file that looks like this.

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

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

Basically I need to do calculations the average item number used for each date using arrays and do some other calculations with the cost. I'm getting really hung up with loading the data from the file and manipulating it for equations. This is what I have so far.

#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;

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

I haven't started working with the equations yet since I still can't get the file loaded in a simple array!!!

谢谢!

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

推荐答案

在解决这类问题时,我希望将其分解为与解析相关的部分.我正在使用一些标准库为我做一些工作.我还创建了两个结构来帮助保持数据信息的有条理.至于您的日期,我可以将其保留为一个单独的 std :: string ,但我选择将 date 本身分解为三种类型并将其存储到数据中结构只是为了显示与解析有关的功能之一的功能.

When working on these kinds of problems I like to break these down into the parts related to parsing. I'm using some of the standard libraries to do some of the work for me. I also created a couple of structures to help keep the information of the data organized. As for your date, I could of left that as a single std::string but I chose to break the date down into three individual types themselves and store them into a data structure just to show the capabilities of one of the functions that is involved with parsing.

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

What I prefer doing is to get either a single line of data from a file and save that to a string, or get the entire contents of a file and save that either to a large buffer or a vector of strings, unless if I'm handling specific type of code where that is not applicable such as parsing a wav file. Then close the file hand as I'm done reading from it! Then after I have all of the information I need, instead of trying to parse the file directly while it is opened I'd rather parse a string as it is easier to parse. Then after parsing the string we can populate our data types that we need.

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

I had to modify your data file slightly to accommodate for the extra white spaces so I saved your file as a text file with only a single white space between each data type within a single line of text. I also did not include the first line (header) information as I just omitted it completely. However this should still act as a guide of how to design a good work flow for an application that has good readability, reusability, try to keep it portable and as generic as possible. Now, what you have been waiting for; the demonstration of my version of your code:

#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;
}

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

NOTE This will not work with how your file currently is; this does not account for the first line of text (header information) and this does not account for any extra white spaces in between the data fields. If you add a single line of text when opening the file and read in a single line and just ignore it, then perform the loop to get all strings to add to vector to return back; your vectors will have the information in it but they will not be at the correct index locations of the vector because of all the extra white spaces. This is something you need to be aware of! Other than that; this is how I would basically design a program or application to parse data. This is by all means not 100% full proof and may not even be 100% bug free, but from a quick glance and running it through my debugger a few times it does appear to be without any noticeable bugs. There could also be some room for improvements for runtime efficiency, etc. but this is just a generalization of basic parsing.

这篇关于C ++数据文件,数组和计算分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆