簡體   English   中英

如何將從文件中讀取的字符串與枚舉值相關聯?

[英]How do I associate a string read from a file to an enum value?

問題

我不確定枚舉值如何與字符串輸入相關聯。 我的意圖是從文件中讀取數據,一旦到達某個getline分隔符,該字符串應與數組中對象的taxCategory相關聯。 我確實查看了其他SO線程,但是它們都沒有顯示如何將其他值與不同的枚舉值相關聯。

我看到可以使用模板執行此操作,但是我還沒有學到任何有關模板的信息。

具有行號的所有代碼的鏈接

GrItem.cpp http://pastebin.com/C4jmKcUt問題所在的行是81和136。

StoreInfo.h http://pastebin.com/uh4armvs

快速代碼信息

此代碼僅用於將稅種讀為字符串並將其保存到正確的taxCategory變量中。 我不確定是否應該從字符串中刪除定界符,因為以后可以這樣做。 但是,如果需要刪除字符串的確定和每個taxCategory的稅額的計算,那么我會找出一種方法。

// Read tax category
getline(nameFile, input, '#');
vectorList[count].taxCategory = input;// Casts string to a double

該選項僅用於將稅收類別打印到用戶的屏幕上。 目的是使字符串以列表格式移至右側。

std::cout << vectorList[i].GrListItem::taxCategory << endl;// Print tax category
std::cout.width(20);
std::cout.fill(' ');

完整代碼

#include "stdafx.h"
#include "StoreInfo.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <map>

using namespace std;

// Tax rate catagories
const double alcoholTax = 0.08;
const double foodTax = 0.05;
const double genMerchandiseTax = 0.07;
const double medicineTax = 0.04;

struct cost{
    double alcTax = 0.0, food = 0.0, genMerch = 0.0, meds = 0.0;// Total taxes collected for each tax bracket
    double totalTax = alcTax + food + genMerch + meds;// Total Taxes to be accessed later

    // Variables used in the accessor functions at the bottom
    double costBeforeTax = 0.0, costAfterTax = 0.0, custSaving = 0.0, totRegPrice = 0.0, totSalePrice = 0.0;
};

const int listSize = 20;
// Main method
int main(){

    string input;// Holds each line from the imported textfile temporarily
    string fileName;// Name of grocery list user wishes to use
    fstream nameFile;// File stream object
    GrListItem itemList[listSize];// Creates a list of objects. These objects are each item on the list and hold related information
    std::vector<GrListItem> vectorList(itemList, itemList + listSize);
    cost itemTotalCost;

    // Create a map from strin to enum
    std::map<std::string, taxCategory> EnumMap;
    EnumMap = enumMap;

    // Initialize
    EnumMap["alcohol"] = one;
    EnumMap["food"] = two;
    EnumMap["general merchansise"] = three;
    EnumMap["medicine"] = four;

    // Convert strings to enums
    std::string key = "alcohol";


    // Requests data from user
    cout << "What is the name of the grocery list you wish to use? " << endl;
    getline(cin, fileName);// Retrieves filename from user and applies string to grListName

    // Tests to see if file can be opened
    fstream testFile(fileName, ios::out);
    if (testFile.fail()){
        cout << "ERROR: Cannot open indicated file.\n";
        return 0;
    }

    // Open data file
    nameFile.open(fileName, ios::in);
    // Read data and apply variables to an object
    if (nameFile){
        int count = 0;
        while (nameFile && count < listSize){

            // Read the name
            getline(nameFile, input, '#');
            vectorList[count].name = input;// Assigns item name to the object inside itemList.name

            // Read quantity
            getline(nameFile, input, '$');
            vectorList[count].quantity = atoi(input.c_str());// Casts string to an int

            // Read regular price
            getline(nameFile, input, '$');
            vectorList[count].regPrice = stof(input.c_str());// Casts string to a float

            // Read sale price
            getline(nameFile, input, '#');
            vectorList[count].salePrice = stof(input.c_str());

            // Read on sale bool
            getline(nameFile, input, '#');
            if (vectorList[count].onSale == 'Y')// If the item is on sale, the isOnSale var returns true 
                vectorList[count].isOnSale == 1;
            else
                vectorList[count].isOnSale == 0;
            vectorList[count].onSale = atoi(input.c_str());

            // Read tax category
            getline(nameFile, input, '#');
            vectorList[count].taxCategory = input;// Casts string to a double

            // These functions are called as many times as there are objects in the array. 
            getTotBeforeTax(vectorList[count].regPrice, vectorList[count].salePrice, vectorList[count].isOnSale);
            //getTotTaxCategory(taxCategory);
            getTotAfterTax(itemTotalCost.costBeforeTax, itemTotalCost.totalTax);

            count++;
        }
        // Close file
        nameFile.close();
    }
    else
        cout << "ERROR: Cannot open file.\n";

    // Sort array 
    // OFFER USER TO CHOOSE HOW THEY WOULD LIKE TO SORT THEIR LIST!!! For extra points
    // Maybe
    std::sort(vectorList.begin(), vectorList.end(), sortByName);

    // For loop that creates a receipt on the screen
    // Formatting may or may not be correct
    for (int i = 0; i != listSize; ++i){
        std::cout << vectorList[i].name << endl;// Print item name
        std::cout << std::setfill(' ') << std::setw(20);
        std::cout.fill(' ');

        std::cout << std::setfill(' ') << std::setw(5);// Print item quantity
        std::cout << vectorList[i].quantity << endl;
        std::cout.fill(' ');

        std::cout << std::setfill(' ') << std::setw(5);// Print regular price of item
        std::cout << vectorList[i].regPrice << endl;// Adjust preci
        std::cout.fill(' ');

        std::cout << std::setfill(' ') << std::setw(5);// Print sale price of item
        std::cout << vectorList[i].salePrice << endl;
        std::cout.fill(' ');

        if (vectorList[i].onSale == 1){
            std::cout << 'Y' << endl;// Print 'Y' if vectorList[i] is on sale
            std::cout.width(3);
            std::cout.fill(' ');
        }
        else {
            std::cout << 'N' << endl;// Print 'N' if vectorList[i] is not on sale
            std::cout.width(3);
            std::cout.fill(' ');
        }

        std::cout << vectorList[i].GrListItem::taxCategory << endl;// Print tax category
        std::cout.width(20);
        std::cout.fill(' ');
    }

    // Print details of purchase below list of bought items

    // NOTE: THESE VALUES ARE STORED IN THE STRUCT ABOVE main()
    // Display total before tax
    // Display total after tax
    // Display customer Savings

}

// Constructor
GrItem::GrItem(string name, int quantity, float regPrice, float salePrice, bool onSale, enum GrListItem::taxCategory taxCategory){

    name = name;
    quantity = quantity;
    regPrice = regPrice;
    salePrice = salePrice;
    onSale = onSale;
    enum GrListItem::taxCategory tax = taxCategory;

};

// Default constructor
GrItem::GrItem() {
}

// Associate the value of the item's tax based on the taxCategory enum
void calcTaxCategory(enum taxCat taxCat){

}

// Get the total cost before the tax
void getTotBeforeTax(double regPrice, double salePrice, bool onSale){
    cost itemTotalCost;
    if (onSale == 1){
        itemTotalCost.costBeforeTax += salePrice;
        itemTotalCost.totSalePrice += salePrice;
    }
    else{
        itemTotalCost.costBeforeTax += regPrice;
        itemTotalCost.totRegPrice += regPrice;
    }
}

// Get the total after tax
void getTotAfterTax(float costBeforeTax, float totalTax){
    cost itemTotalCost;
    itemTotalCost.costAfterTax = costBeforeTax + totalTax;
}

// Get the total amount of tax for each category
void getTotTaxCategory(enum taxCat taxCat){// These different values are determined by what enum tax category they are
    cost itemTotalCost;


}

// Get customer savings (total of all differences between regular price and sale price for items that are currently on sale)
void getCustSave(double totRegPrice, double totSalePrice, bool onSale){
    cost itemTotalCost;
    if (onSale == 1){
        itemTotalCost.custSaving = totRegPrice - totSalePrice;
    }

}

// Function that is called to sort by name
bool sortByName(const GrListItem &lhs, const GrListItem &rhs){
    return lhs.name < rhs.name;
}

// Function that is called to sort by quantity
bool sortByQuantity(const GrListItem &lhs, const GrListItem &rhs){
    return lhs.quantity < rhs.quantity;
}

// Function that is called to sort by regular price
bool sortByRegPrice(const GrListItem &lhs, const GrListItem &rhs){
    return lhs.regPrice < rhs.regPrice;
}

// Function that is called to sort by sale price
bool sortBySalePrice(const GrListItem &lhs, const GrListItem &rhs){
    return lhs.salePrice < rhs.salePrice;
}

如果要將字符串與枚舉關聯,則可以使用幾個選項。 這是其中兩個:

選項1:使用字符串的const數組。 掃描與您輸入的匹配項,並將匹配字符串的索引轉換為枚舉值。 (當然要處理不匹配的情況)

enum MyEnum {one, two, three, error};
const char * stringToEnum[] = 
    {"One", "Two", "Three"};
string key = "Two"; // for example
MyEnum e = error;
for(size_t index = 0; index < (sizeof(stringToEnum)/sizeof(stringToEnum[0])); ++index)
{
   if(key == stringToEnum[index])
   {
      e = MyEnum(index);
      break;
   }
}

選項2:創建從字符串到枚舉的映射。 需要運行時初始化,但是解析該值的代碼很簡單:

聲明地圖:

#include <iostream>
#include <map>

enum MyEnum {error, one, two, three};
typedef std::map<std::string, MyEnum> EnumMap;
EnumMap enumMap;

初始化地圖:

int main()
{
    enumMap["One"] = one;
    enumMap["Two"] = two;   
    enumMap["Three"] = three;

使用映射將字符串轉換為枚舉首先使用[]運算符:

    std::string key = "Two";
    std::cout << key << "=" << enumMap[key] << std::endl;
    key = "Three";
    std::cout << key << "=" << enumMap[key] << std::endl;
    // this will add a bogus entry to the table
    // do not use [] if your input may contain bad keys.
    key = "Five";
    std::cout << key << "=" << enumMap[key] << std::endl; 

這是到目前為止的輸出:

Two=2
Three=3
Five=0

現在,使用at()方法嘗試相同的操作:

    key = "Two";
    std::cout << "At: " << key << "=" << enumMap.at(key) << std::endl;
    key = "Three";
    std::cout << "At: " << key << "=" << enumMap.at(key) << std::endl;
    // this will find the zero entry added by the [] operator
    key = "Five";
    std::cout << "At: "  << key << "=" << enumMap.at(key) << std::endl;
    // this will throw an exception
    key = "Seven";
    std::cout << "At: "  << key << "=" << enumMap.at(key) << std::endl;

這是使用at()方法的輸出:

At: Two=2
At: Three=3
At: Five=0
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM