Reading Multiple Words from a file

I am writing up a code that involves inputting data from a file into an array of structs. The objective of this code is to create an array of structs for a list of menu items. The struct contains the string MenuItem for the menu items and the double MenuPrice of the item price. I'm having trouble with the data file because the given data file has a varying words for the menu item.
This is code I tried.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>

using namespace std;

const int NO_OF_MENU_ITEMS = 8;

struct menuItemType
{
	string MenuItem;
	double MenuPrice;
};

void getMenuFromFile(ifstream& inFile, menuItemType menu[], int menuSize);

int main()
{
    menuItemType menu[NO_OF_MENU_ITEMS];
    int choiceListLength = 0;
    ifstream inFile;

	inFile.open("menuData.txt");

    if (!inFile)
    {
        cout << "Cannot open the input file. Program Terminates!" << endl;
    }
	else
	{
		getMenuFromFile(inFile, menu, choiceListLength); 
		inFile.close();
	}

    system("pause");
	return 0;

void getMenuFromFile(ifstream& inFile, menuItemType menu[], int menuSize)
{
     for (menuSize=0; menuSize < NO_OF_MENU_ITEMS; menuSize++)
		{
		inFile >> menu[menuSize].MenuItem >> menu[menuSize].MenuPrice;
                }
}


The text file is formatted like this:
1
2
3
4
5
6
7
8
Plain Egg 1.45
Bacon and Egg 2.45
Muffin 0.99
French Toast 1.99
Fruit Basket 2.49
Cereal 0.69
Lemon Tea 0.75
Cheeseburger 2.25

You need a delimiter such as '$', or ':' to mark the end of one input and the beginning of another. I would change the input file like this.
1
2
3
4
5
6
7
8
Plain Egg $1.45
Bacon and Egg $2.45
Muffin $0.99
French Toast $1.99
Fruit Basket $2.49
Cereal $0.69
Lemon Tea $0.75
Cheeseburger $2.25


Once you have the delimiter in place you can use getline to retrieve the data like this.

1
2
3
4
5
6
7
8
9
10
11
void getMenuFromFile(ifstream& inFile, menuItemType menu[], int menuSize)
{
     
	
	for (menuSize=0; menuSize < NO_OF_MENU_ITEMS; menuSize++)
		{
			getline (inFile,menu[menuSize].MenuItem, '$');    //<------ gets a string up to the $ character and assigns to struct
			inFile >> menu[menuSize].MenuPrice; // <---------------- gets the price after the $ character and assigns to struct 
			inFile.ignore(1000, '\n');    //<----------------------- Ignores any newlines           
		}
}





Wow, that's amazing. That function worked perfectly. I never knew getline can be used like that. Am I suppose to post my new code (it's basically the same thing with that new function added)?
stringstream
http://www.cplusplus.com/doc/tutorial/basic_io/

std::string::append
http://www.cplusplus.com/reference/string/string/append/

std::getline (string)
http://www.cplusplus.com/reference/string/string/getline/

menuData.txt
1
2
3
4
5
6
7
8
Plain Egg 1.45
Bacon and Egg 2.45
Muffin 0.99
French Toast 1.99
Fruit Basket 2.49
Cereal 0.69
Lemon Tea 0.75
Cheeseburger 2.25


My code - rewritten your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;

const int NO_OF_MENU_ITEMS = 8;

struct menuItemType
{
	string MenuItem;
	double MenuPrice;
};

void getMenuFromFile(ifstream& MYinFile, menuItemType MYmenu[])
{
    string strLine="";
    string strMenuItem="";
    string strPrice="";
    int LastEmptyPos;
    int j=0;

    while ( getline(MYinFile,strLine) && (j<NO_OF_MENU_ITEMS) )
    {
        for (int i=0; i<strLine.size(); i++)
            if (strLine[i]==' ') LastEmptyPos = i;

        strMenuItem="";
        MYmenu[j].MenuItem=strMenuItem.append(strLine,0,LastEmptyPos);
        cout<<MYmenu[j].MenuItem<<endl;

        strPrice="";
        strPrice=strPrice.append(strLine,LastEmptyPos+1,strLine.size()-LastEmptyPos);
        stringstream (strPrice) >> MYmenu[j].MenuPrice;
        cout<<MYmenu[j].MenuPrice<<endl<<endl;

        j++;
    }
}

void printStructMembers (menuItemType MYmenu[]) {
    for (int j=0; j<NO_OF_MENU_ITEMS; j++) {
        cout << "menu["<<j<<"].MenuItem  = " << MYmenu[j].MenuItem  << endl;
        cout << "menu["<<j<<"].MenuPrice = " << MYmenu[j].MenuPrice << endl <<endl;
    }
}

int main()
{
    string strline;
    menuItemType menu[NO_OF_MENU_ITEMS]; // array of structs of menuItemType
    ifstream inFile("menuData.txt");     // open file with constructor

    if ( inFile.is_open() )
        getMenuFromFile(inFile, menu);   // passing file and array of structs

    else
	cout << "Cannot open the input file. Program Terminates!" << endl;

    inFile.close();

    printStructMembers (menu);

    return 0;
}
Plain Egg
1.45

Bacon and Egg
2.45

Muffin
0.99

French Toast
1.99

Fruit Basket
2.49

Cereal
0.69

Lemon Tea
0.75

Cheeseburger
2.25

menu[0].MenuItem  = Plain Egg
menu[0].MenuPrice = 1.45

menu[1].MenuItem  = Bacon and Egg
menu[1].MenuPrice = 2.45

menu[2].MenuItem  = Muffin
menu[2].MenuPrice = 0.99

menu[3].MenuItem  = French Toast
menu[3].MenuPrice = 1.99

menu[4].MenuItem  = Fruit Basket
menu[4].MenuPrice = 2.49

menu[5].MenuItem  = Cereal
menu[5].MenuPrice = 0.69

menu[6].MenuItem  = Lemon Tea
menu[6].MenuPrice = 0.75

menu[7].MenuItem  = Cheeseburger
menu[7].MenuPrice = 2.25
Last edited on
Topic archived. No new replies allowed.