【问题标题】:C++ Data files, arrays, and calculations assignmentC++ 数据文件、数组和计算分配
【发布时间】:2018-10-30 03:08:55
【问题描述】:

我是 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

【问题讨论】:

  • 您可以发布您要加载的文件吗?我想我在问它是否是您帖子顶部所示的文本文件,或者它是否是某种二进制文件。
  • int itemnum[][]; -- 这不是有效的 C++,也不是任何与此相似的行。
  • 我故意将这些留空 - 我应该在括号中放置一个变量来表示 itemnum 还是 numbers?
  • @Nick 我应该在 itemnum 或 numbers 的括号中放置一个变量吗? -- 这是您遗漏的最重要的部分。您不能将运行时值放在括号中——数组的大小是固定的。你知道要阅读的最大项目数吗?如果没有,那么你不能使用数组——改用std::vector。如果您确实知道最大条目数,则将读取的最大条目数放在括号中。您不能将它们留空——这不是有效的 C++。

标签: c++ arrays file


【解决方案1】:

在处理这类问题时,我喜欢将它们分解为与解析相关的部分。我正在使用一些标准库为我做一些工作。我还创建了几个结构来帮助组织数据信息。至于您的日期,我可以将其保留为单个 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% 没有错误的,但快速浏览并通过我的调试器运行它几次,它似乎没有任何明显的错误。在运行时效率等方面也可能有一些改进空间,但这只是基本解析的概括。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 2013-06-30
    • 2020-02-28
    相关资源
    最近更新 更多