我是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
答案 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%的错误,但是快速浏览并通过我的调试器运行了好几次,它似乎没有任何明显的错误。在运行时效率方面还可能有一些改进的空间,等等。但这只是基本解析的概括。