Functions and I/O Files

I am working on an assignment that must read input from a file, but as per my instructor's directions, "Make sure you use functions, a function for each of the calculations, one to read in one line of data, one to write one line of data, one for the output column labels, etc."

So, basically, all of my stuff has to happen in functions. My main question right now is, how do I make it so that the program goes to a function, reads in a line, transfers that back and then goes back to that function and reads in the next line from the file? I appreciate your help in advance!

This is what I have so far, just the very beginning:

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
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

void getInput(string &);

int main()
{
    string foodName;
    
    getInput(foodName);
    cout << foodName1 << endl;
    
    return 0;
}


void getInput1(string &name)
{
    ifstream inputFile;
    inputFile.open("/Users/---/Documents/caloric.txt");
    
    getline(inputFile, name);
}
If all the functions will be working on the file, then the file should be declared and opened in main, and be passed to all the functions by reference.
Thanks! That helped me get past that first little hump. Now, I'm at a new problem. Here's my code now:

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
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

void getInput(istream &, string &, string &, float &, float &, float &);

int main()
{
    string foodName, servSize;
    float foodCals, actInten, actMin;
    
    ifstream inputFile;
    inputFile.open("/Users/jordanfleming/Documents/programinput.txt");
    
    //while (!inputFile.eof())
    //{
        getInput(inputFile, foodName, servSize, foodCals, actInten, actMin);
        cout << foodName << servSize << foodCals << actInten << actMin << endl;
    //}
    
    inputFile.close();
    
    return 0;
}

void getInput(istream &file, string &name, string &size, float &cals, float &inten, float &min)
{
    getline(file, name);
    getline(file, size);
    file >> cals;
    file >> inten;
    file >> min;
}


I have "//"'d out the while loop seen in the code because it creates an infinite loop, and I'm not sure why. Without the loop, the program prints out the first set of data just fine. My file contains the following data:

T-Bone Steak (Broiled or Grilled)
8 Ounces
420
17
20
Bananas (Fresh)
4 Ounces
200
5
40
Pecans (Halves)
1 Ounce
190
12
24
Salmon (Atlantic)
16 Ounces
625.5
9
30
Spider Roll (Fried Soft-Shell Crab)
8 Ounces
317
6
15
Asparagus (Raw)
16 Ounces
56
1
60
Singapore Sling
8 Ounces
230
11
20

Can anyone help?
The problem is that you should never loop on EOF. The problem is, when you reach the end of the file, the EOF flag is not set, so the next read operations all fail and you print out the data from the previous read. The read operations have to fail for the EOF flag to be set.

Instead, change your getInput function to return the reference to the istream so you can use the function call as the condition of the while loop:
16
17
18
19
    while(getInput(inputFile, foodName, servSize, foodCals, actInten, actMin))
    {
        cout << foodName << servSize << foodCals << actInten << actMin << endl;
    }
When the read operation fails, the while loop will stop then because the condition is false, and you won't get extra data printed out.
Last edited on
I'm not quite sure how my function needs to be changed. Could you elaborate?
Change the return type from void to istream & and add a return file; at the end.
Ok, tried that and it is only printing out the first set of data.
it is only printing out the first set of data.
Probably the issue here is the mixing of getline() and the >> operator.

The getline() function reads an entire line and discards the newline character '\n' at the end of the line. On the other hand, the >> operator (e.g. file >> min;) will skip any leading whitespace, but leave the rest of the line untouched, in particular there will be a trailing newline character in the input file buffer afterwards.

On the second call to function getInput() that unwanted newline will be picked up by the first getline(), and everything will get out of synchronisation, character data such as "Ounces" will be found when attempting to read a float, the file status will be set to fail and the while loop will terminate.

I don't know whether I explained that very well. But the solution is to remove the unwanted newline character like this in function getInput():
1
2
    file >> min;
    file.ignore(1000, '\n'); // remove unwanted newline 

http://www.cplusplus.com/reference/istream/istream/ignore/
I follow you, I had wondered about whether the mix of those was a bad practice, but I don't really know how else to do it (?). Adding the file.ignore(1000, '\n'); printed out the rest of the data except the very last one. So, now I'm pondering that one. Thanks for your help.
I think the reason for the last set of data not being printed is a side-effect of adding the ignore(). If there is no newline at the end of the last line in the file the ignore() won't be able to find anything to ignore, and thus will set the file status to fail, which in turn will stop the body of the while loop from being executed.

In order to fix that I suggest removing that file.ignore() from inside the getInput() function, and instead put it inside the body of the while loop, that way it shouldn't interfere with the printing of the last set of data.
Topic archived. No new replies allowed.