C ++如何加载文本文件并将内容添加到类中?

时间:2017-05-23 20:29:35

标签: c++

我正在努力学习如何使用课程,我想我会创建一些超市系统来帮助我学习。将文本文件中的所有值保存到临时变量后,如何使用它们创建对象?我假设我想要“购买”每个项目一个对象?

如果您有关于如何改进我的代码的任何其他提示,请在几天前我刚开始使用C ++时提及它们。

我的文字文件如下:

42 68 Apples
35 1 Oranges
70 25 Bananas

我的代码如下:

// Classes.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>

class Products {
private:
    int price;
    int ID;
    int quantity;

public:
    void setPrice(int newPrice) {
        price = newPrice;
    }
    void setID(int newID) {
        ID = newID;
    }
    void setQuantity(int newQuantity) {
        quantity = newQuantity;
    }

    int getPrice() {
        return price;
    }
    int getID() {
        return ID;
    }
    int getQuantity() {
        return quantity;
    }

};


int main()
{
    std::string line;
    std::string input;
    std::string temp;
    std::string temp2;
    std::string temp3;

    int counter = 0;
    while (input != "e" && input != "r") {
        std::cout << "Do you want to (r)ead the inventory or (e)dit it? (input 'r' or 'e'): ";
        getline(std::cin, input);
    }
    if (input == "r") {
        std::ifstream pFile ("products.txt");
        if (pFile.is_open()) {
            while (getline(pFile, line)) {
                std::istringstream iss(line);
                iss >> temp >> temp2 >> temp3;
                counter++;


            }
        }

    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

查看您正在使用的文本文件,并尝试使用以下信息填充一组类:

文字档案

42 68 Apples
35 1 Oranges
70 25 Bananas

查看文本文件后,您有int后跟space,然后是另一个int,后跟另一个space,最后是varying size of char[]。我们可以使用此信息来创建您的classstruct,这就是我根据正在读取或解析的文件中的内容创建class的方法。

<强> Produce.h

#ifndef PRODUCE_H
#define PRODUCE_H

#include <string>

class Produce {
private:
    unsigned price_;   // Normally would use float but will use unsigned for simplicity
    unsigned quantity_;
    std::string name_; // You could use the int as an id as you were using

public:
    Produce() {} // Default Constructor

    ~Produce() {} // Default Destructor

                  // User Constructor
    Produce(const std::string& name, const unsigned& price, const unsigned& qty )
        : name_(name), price_(price), quantity_( qty ) {}

    // Copy By Const Reference Constructor
    Produce(const Produce& other) {
        name_     = other.name_;
        price_    = other.price_;
        quantity_ = other.quantity_;
    }

    // Assignment Operator
    Produce& operator=(const Produce& other) {
        name_     = other.name_;
        price_    = other.price_;
        quantity_ = other.quantity_;
        return *this;
    }

    // Setters & Getters
    void setOrChangePrice(const unsigned& priceChange) {
        price_ = priceChange;
    }
    unsigned getPrice() const { return price_; }

    void setName(const std::string& name) {
        // Already Has A Name? Return!
        if (!name_.empty())
            return;
    }
    std::string getName() const { return name_; }

    void setOrChangeQuantity(const unsigned& qty) {
        quantity_ = qty;
    }
    unsigned getQuantity() const {
        return quantity_;
    }

};

#endif // PRODUCE_H

<强> Produce.cpp

#include "Produce.h"

// Normally Constructor(s) & Function Definitions Would Go Here
// Since this is a simple class; I declared & defined them in the header.

<强> Inventory.h

#ifndef INVENTORY_H
#define INVENTORY_H

#include <vector>

#include "Produce.h"

class Inventory {
private:
    std::vector<Produce>  produce_;

public:
    Inventory() {}
    ~Inventory() {
        if (!produce_.empty()) {
            produce_.clear();
        }
    }

    std::vector<Produce> getProduceList() const {
        return produce_;
    }

    unsigned getProduceListSize() const {
        return static_cast<unsigned>( produce_.size() );
    }

    void addProduce(const Produce& produce) {
        produce_.push_back(produce);
    }

    Produce getProduce(const std::string& name) const {
        for (unsigned n = 0; n < produce_.size(); ++n) {
            if (name == produce_[n].getName()) {
                return produce_[n];
            } else {
                return Produce();
            }
        }
    }

    unsigned getPrice(const std::string& name) const {
        for (unsigned n = 0; n < produce_.size(); ++n) {
            if (name == produce_[n].getName()) {
                return produce_[n].getPrice();
            } else {
                return 0;
            }
        }
    }

    unsigned getQuantity( const std::string& name ) const {
        for (unsigned n = 0; n < produce_.size(); ++n) {
            if (name == produce_[n].getName()) {
                return produce_[n].getQuantity();
            } else {
                return 0;
            }
        }
    }   
};

#endif // INVENTORY_H

<强> Inventory.cpp

#include "Inventory.h"

<强> Main.cpp的

// #include <vector> // Also Included In Inventory.h
// #include <string>    // Also Included In Produce.h
#include <iostream>
#include <fstream>

// #include "Produce.h"  // Also Included In Inventory.h
#include "Inventory.h"

int main( ) {
    // Same As Your Text File
    std::string strFilename("ProduceInventory.txt");    
    std::ifstream fileIn;

    // Temps
    unsigned price = 0;
    unsigned qty   = 0;
    std::string name;

    Inventory inventory;

    fileIn.open(strFilename.c_str());
    if (!fileIn.is_open()) {
        std::cout << "Can not read file\n";
    }

    while (fileIn >> price >> qty >> name) {
        Produce produce(name, price, qty);
        inventory.addProduce(produce);
    } 

    if ( fileIn.is_open() ) {
        fileIn.close();
    }

    // Test Our Inventory From File
    for (unsigned n = 0; n < inventory.getProduceListSize(); n++) {
        std::cout << "Name: " << inventory.getProduceList()[n].getName() << " "
        << "Price: " << inventory.getProduceList()[n].getPrice() << " "
        << "Qty: " << inventory.getProduceList()[n].getQuantity() << "\n";
    }
    std::cout << std::endl;

    // Check To See If Our Search Method Works
    std::cout << "Enter a product type by name to get its price and qty on hand.\n";
    name.clear(); // reuse
    std::cin >> name;

    Produce p = inventory.getProduce(name);
    if (p.getName().empty()) {
        std::cout << "We either do not carry this produce or we are out of stock\n";
    } else {
        std::cout << "Our price is " << p.getPrice() << " and we have " << p.getQuantity() << " on hand\n";
        // Or
        std::cout << "Our price is " << inventory.getPrice(name) << " and we have " << inventory.getQuantity(name) << " on hand\n";
    }

    return 0;
}

现在这只是可以做到的很多方法之一;还要确保您的文本文件位于IDE工作目录的适当位置,或者您指定了正确的路径以及文件名和扩展名,以便能够首先打开和读取该文件。

这些代码中的大部分都可能被罚款更多;但我正在展示如何使用std::vector<T>容器及其一些功能,以及如何迭代它们并检索其数据。当您知道文本文件的确切格式时,这是解析简单文本文件的基本方法,并且对于每一行,您将以相同的顺序具有相同的数据类型。

这不适用于每种文件解析,因为它取决于文件的格式。例如,另一个文件可能具有从一行到下一行的不同类型的数据,并且可能具有关键字或标签以描述接下来将要出现的数据类型。对于那种解析,您必须首先将整行读入字符串流,然后您必须能够通过令牌解析该字符串流以提取数据。有时解析文件可能有多行属于一个数据集,因此您必须通过块或blob进行解析。

解析文本文件比二进制文件格式更难解析,因为你必须检查文本的每一行和字符,你还必须谨慎 字符返回,新行字符等。使用二进制格式,您只需要知道要读入多少字节以及预期的数据类型。关于如何从文件中解析数据,仅就此主题编写了许多书籍。没有一种适合所有人的简单方法。