I have written a code that asks the user a name (ex.candy) and a number then it stores it in a stuff.txt file like so:

"
candy
20
candy
40
decorations
70
costumes
40
candy
60
"

When reading from that stuff.txt file, how can I add the running total for let say candy?
I want the program to recognize the string "candy" then adds the running total of the numbers below it then display it in a cout.

The part of the code that I am having trouble with:

ifstream file;

    file.open("stuff.txt", ios::out);
    cout << "You chose total sales for today.\n";
    if (file.fail())
    {
        cout << "Error opening input file\n\n";
    }
    else
    {
        string candy, costumes, decorations;
        if (file)
        {
            getline(file, candy); 
            file >> totalCandy; 
            cout << candy << "\n" << totalCandy; 
            file.get(); 
            file.get(); 

            getline(file, costumes); 
            file >> totalCostumes; 
            cout << costumes << "\n" << totalCostumes; 

            getline(file, decorations); 
            file >> totalDecorations; 
            cout << decorations << "\n" << totalDecorations; 

            file.close(); 
            file.clear(); 
        }
    }

Thanks in advance!! (:

Recommended Answers

All 18 Replies

Your main problem is not having a loop to read through the file.

For storing the totals a map<string, int> would work well. Read the file storing the totals in a map object. Now you can display whichever total is required. A simple menu would work well for that.:

#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;

int main()
{
    ifstream file;
    map<string, int> salesTotals;
    file.open("stuff.txt", ios::out);
    if (file.fail())
    {
        cout << "Error opening input file\n\n";
        cin.get();
        return -1;
    }
    else
    {
        while (file)
        {
            string tempSalesType;
            int tempSales;
            //Read sales type
            getline(file, tempSalesType);
            //If it isn't in the map, add it
            if (salesTotals.find(tempSalesType) == salesTotals.end())
            {
                salesTotals.emplace(tempSalesType, 0);
            }
            //Read sales amount
            file >> tempSales;
            //Increment total
            salesTotals[tempSalesType] += tempSales;
            //Read to the end of the line
            getline(file, tempSalesType);
        }
    }
    file.close();
    char choice = '1';
    while (choice != '0')
    {
        cout << "You chose total sales for today.\n";
        cout << "1. Candy\n";
        cout << "2. Costumes\n";
        cout << "3. Decorations\n";
        cout << "0. Quit\n";
        cin >> choice;
        switch (choice)
        {
        case '1':
            cout << "\n\nCandy total - " << salesTotals["candy"] << "\n\n";
            break;
        case '2':
            cout << "\n\nCostumes total - " << salesTotals["costumes"] << "\n\n";
            break;
        case '3':
            cout << "\n\nDecorations total - " << salesTotals["decorations"] << "\n\n";
            break;
        case '0':
            break;
        default:
            cout << "Only numbers 0-3 please.\n";
        }
    }
    return 0;
}

Thank you so much for the post, tinstaafl.
I have not yet covered #include <map> so I am not able to use it but it looks like something really cool to check it so I will do so later.

If it is not much to ask, my professor told me that it can be done with a "for loop" but I still cannot figure out how, so if time allows please give me a hint or an example on how it will work using the for loop.

Thanks again! I really appreciate it.

If you know what all of the types are then youcould do something like the folowing

while getting records from the file
    if type == candy
        add amount to candy total
    else if type == costumes
        add amount to costumes total
    else if type == decorations
        add amount to decorations total

If you do not know how many types will be involded then you will need to use 2 parallel arrays which gets a little more complicated.

NathanOliver, there are only (candy, costumes, & decorations) but I am not really sure what you are referring to by the word 'type.'

type is just a name for what the sales type is in the file. Every time you loop through readin the file you need to read 2 lines. You need to read the type and the amount.

I think I have a pretty good idea of what you are referring to but I am still confused on what to put in for 'type' if the words (candy, costumes, & decorations) are strings.

Please give me an example if the words in file are strings and the numbers under are just doubles, thank you!

Edit:
Here are my instructions; hopefully it will clear up any confusion

"If the file opens properly, read in a c-string from the file. Check to see if the c-string is the word “Candy”, “Costumes”, or
“Decorations”. If it is Candy, then input the amount on the next line and then add to the running total for candy sales. If
it is Costumes, then input the amount on the next line and then add to the running total for costume sales. If it is
Decorations, then input the amount on the next line and then add to the running total for decoration sales."

Here is a better example for you.

//...

std::string type;
int count;
int candyTotal = 0;
int costumesTotal = 0;
int decorationsTotal = 0;

std::ifstream fin("myfile.txt");  // open file

while we read in what type of item we have keep looping through the file
while(std::getline(fin, type))
{
    fin >> count;
    if (type == "candy")
        candyTotal += count;
    else if (type == "costumes")
        costumesTotal += count;
    else if (type == "decorations")
        decorationsTotal += count;

    // ignore '\n' left in buffer from `>>`
    fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

//...
commented: Thanks for your help! +0

Yes, this is exactly what I had in mind but with the updated code, it only gets the first value of candy (2.19) and does not add the rest of the values for some reason.

#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;

int main()
{
string type;
double count, runningCandy;

if (mainMenuChoice == 2)
            {
                ifstream file;
                file.open("sales.txt", ios::out);
                response = 'n'; //ignore

                cout << "You chose total sales for today.\n";
                if (file.fail())
                    cout << "Error opening input file\n\n";
                else
                {
                    while (getline(file, type))
                    {
                        file >> count;
                        if (type == "candy") //trying candy by itself to test.
                            runningCandy += count;
                        cout << "candy total is" << runningCandy;

                        file.ignore(numeric_limits<streamsize>::max(), '\r\n');
                    }
                    file.close();
                    file.clear();
                }
            }
}

In line 30 you are using 2 delimiters. I dont think that will work. What happenes if you just have '/n?

Oh, it lists them like so
"candy total is2.19candy total is9.88,candy total is27.44"

The problem now is that it does not add them but rather list them.

move line 28 outside of the loop.

I tried doing that but the output is 0.

EDIT:
When I do this code, the output is the sum of all the numbers in the txt file.

else if (mainMenuChoice == 2)
            {
                ifstream file;
                file.open("sales.txt", ios::out);
                response = 'n';

                cout << "You chose total sales for today.\n";
                if (file.fail())
                    cout << "Error opening input file\n\n";
                else
                {
                    while (getline(file, type))
                    {
                        file >> count;
                        if (type == "candy")
                            runningCandy += count;

                        file.ignore(numeric_limits<streamsize>::max(), '\r');
                        file.ignore(numeric_limits<streamsize>::max(), '\n');
                    }

                    cout << "candy total is " << runningCandy;
                    file.close();
                    file.clear();
                }
            }

Here's the same basic code I used earlier, reworked to use 3 variables instead of a map:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
    ifstream file;
    int totalCandy = 0, totalCostumes = 0, totalDecorations = 0;
    file.open("stuff.txt", ios::out);
    if (file.fail())
    {
        cout << "Error opening input file\n\n";
        cin.get();
        return -1;
    }
    else
    {
        while (file)
        {
            string tempSalesType;
            int tempSales;
            //Read sales type
            getline(file, tempSalesType);
            //Read sales amount
            file >> tempSales;
            //Find the right sales type and increment by sales amount.
            if (tempSalesType == "candy")
            {
                totalCandy += tempSales;
            }
            else
            if (tempSalesType == "costumes")
            {
                totalCostumes += tempSales;
            }
            else
            if (tempSalesType == "decorations")
            {
                totalDecorations += tempSales;
            }
            //This is necessary to make sure you don't read anything left over on this line as a sales type.
            getline(file, tempSalesType);
        }
    }
    file.close();
    char choice = '1';
    while (choice != '0')
    {
        cout << "You chose total sales for today.\n";
        cout << "1. Candy\n";
        cout << "2. Costumes\n";
        cout << "3. Decorations\n";
        cout << "0. Quit\n";
        cin >> choice;
        switch (choice)
        {
        case '1':
            cout << "\n\nCandy total - " << totalCandy << "\n\n";
            break;
        case '2':
            cout << "\n\nCostumes total - " << totalCostumes << "\n\n";
            break;
        case '3':
            cout << "\n\nDecorations total - " << totalDecorations << "\n\n";
            break;
        case '0':
            break;
        default:
            cout << "Only numbers 0-3 please.\n";
        }
    }
    return 0;
}
commented: Thanks for your help! +0

tinstaafl, your code did not differ much from what I had previously but for some reason the output is always 0 for ALL 3 (candy, costumes, & decorations). Do you know the reason for that?

stuff.txt has:
"candy
4.39
candy
17.56
costumes
39.51
decorations
53.78"

It doesn't take much of a difference to not work. For instance, you're using ignore instead of an extra getline like I have. This is a big enough change to stop it from working right. When I use your code and get rid of the ignore statements and put in a getline the total comes up right. Assuming of course that count and runningcandy are both float types.

Yes I totally understand but I always end up with 0 for output even when I use getline instead of ignore (I debugged your code to check).
I have debugged the code on 2 computers so far and still same output of 0.

When I read the code, it makes sense but I'm not really sure to why it is not reading the right numbers from file.

step through the code with the debugger or use cout statements and oupt what is happening so you know what is going. Debugging is an important skill to learn.

There must be some detail missing from your code. When I run the last code snippet you added, the total comes up correct, with the changes I mentioned.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.