问题
我有点不确定枚举值如何与字符串输入关联。我的目的是从文件中读取数据,一旦到达某个 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:创建从字符串到枚举的映射。需要运行时初始化,但解析该值的代码非常简单:
声明 map :
#include <iostream>
#include <map>
enum MyEnum {error, one, two, three};
typedef std::map<std::string, MyEnum> EnumMap;
EnumMap enumMap;
初始化 map :
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
关于c++ - 如何将从文件读取的字符串关联到枚举值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23547483/