Program won't output correctly

Hi all, I have written code and my task is to print if a flower grows in the sun or shade. I have a .dat file with a list of flowers in it, but I'm to the point where it prints the first flower, Astilbe, but then times out. Anyone have any suggestions? Thank you!

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
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
    // Declare variables here
    ifstream fin;
    string flowerName;
    string sun_or_shade;
    ifstream data_in;
    ofstream data_out;


    // Open input file
    fin.open("flowers.dat");
    fin >> flowerName;
    fin >> sun_or_shade;
    while (!fin.eof())


        // Write while loop that reads records from file.
        while(!(data_in.eof()))
        {
            data_in >> flowerName;
            data_in >> sun_or_shade;
            cout << flowerName << " grows in the " << sun_or_shade << endl;
        }
    return 0;
} // End of main function 

Here is my list of flowers:
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
Astilbe
Shade
Marigold
Sun
Begonia
Sun
Primrose
Shade
Cosmos
Sun
Dahlia
Sun
Geranium 
Sun
Foxglove
Shade
Trillium
Shade
Pansy
Sun
Petunia
Sun
Daisy
Sun
Aster
Sun
Last edited on
Hi, you have two loops for your input data file when you probably only intended one. The first ifstream object, fin, is never changing its place in the stream, and so is causing infinite while loop. Just use one ifstream object and update its spot.

If the file is consistently in format of <string><whitespace><string>, you can firstly keep it as
Astilbe Shade
Marigold Sun

(don't necessarily need newline)

and do the loop like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
    string file_name("flowers.dat");
    ifstream ifs(file_name);
    if (!ifs)
    {
        cout << "Unable to open \""<<file_name<<"\".  Please check it exists and not in use.\n";
        return -1;
    }

    string flower, sun_or_shade;
    while (ifs >> flower >> sun_or_shade)
    {
        cout << flower << " grows in the " << sun_or_shade << endl;
    }

    return 0;
}

Last edited on
Hello helpwithcplusplus,

As icy1 says you only need one while loop to read the file, but the bigger problem is the while condition based on "eof" and this is what I say about thet:

while(!inFile.eof())

I do not know why people teach this. This is a bad idea as it does not work the way you think it will. Generally by the time the while condition determines that "eof" has been reached you will have processed the last read twice and wondering why it shows up twice.

What happens is the while condition is checked and “eof” has not been set yet. After entering the while loop you read the last line or bit of information from the file process the information reach the bottom of the while loop. At this point “eof” has not been set yet and you return to the while condition which is still good. After entering the loop you try to read from the file, but now there is nothing left to read and “eof” is set, but you do nothing at this point to deal with the “eof” condition. So you process what information is in the variables from the last read before returning to the while condition where it finally detects the “eof”, but you have processed the last good read twice unless you have cleared the variables at the end of the while loop in which case the last process will be blank.
A more acceptable way of using the while loop is:

1
2
3
4
5
while (infile >> someVariable)
{
    infile >> additionalVariables;
    //  Additional code.
}


In the above example you can set up the while condition to read one variable, two or more variables or use “std::getline(?, str)” where ? could be from “std::cin” or from a file stream and “str” represents any “std::string” variable.

Tomorrow I will load up your code and see what it is doing.

Hope that helps for now,

Andy
Hello helpwithcplusplus,

Starting at the top some tips. Between the first line and main a couple of blank lines would be nice. Or even remove line 4 and leave it a blank line.

Inside main:

"Declare variables" you do not need two "ifstream"s just one. And the ofstream is not used right now. OK to leave it if you have a future use for it.

Lines 17 - 19 are not needed. Lines 17 and 18 are reading a file stream only once and then never used.

Line 23 is the while loop yu should use and better written as:
1
2
while (fin >> flowerName >> sun_or_shade)
	cout << flowerName << " grows in the " << sun_or_shade << endl;

The problem you are having with no output is that you are trying to use "data_in" which was never opened. Only "fin" was opened, so you are trying to read a file stream that does not exist.

Once I made those changes it ran fine, And there is no need to change the input file it works fine.

The only thing I can think of that might be a problem is if any flower name would have a space in the name. This could throw the whole program off when it comes to the space. In place of using fin >> flowerName use std::getline(fin, flowerName); in the while condition and a second "getline" inside the while loop to get the lighting.

So unless you are guaranteed that the flower name will always be one word it would be better to use "std::getline()" and be safe.

Hope that helps,

Andy
Hello helpwithcplusplus,

As I was finishing up I realized that I added this just before the return in main. For my self and others this will put a pause in the program to keep the console window open so that the return does not close the program and the console window to soon.

Here is a tip you can use in the future.
1
2
3
4
// The next line may not be needid. If you have to press enter to see the prompt it is not needed.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>.
std::cout << "\n\n Press Enter to continue";
std::cin.get();javascript:editbox1.editPreview()


Andy
Hi all, thanks for your suggestions I will try these out.
Update: I have gotten thus far, it prints all the flowers and whether they are in the sun or shade but skips the first flower, Astilbe. Am I missing anything in my code that makes it skip that?
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
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
    // Declare variables here
    ifstream fin;
    string flowerName;
    string sun_or_shade;
    ifstream data_in;
    ofstream data_out;

    // Open input file
    fin.open("flowers.dat");
    fin >> flowerName;
    fin >> sun_or_shade;
    while (!fin.eof())

    // Write while loop that reads records from file.
      if (fin.is_open())	// Open input file
	{
		while (fin >> flowerName >> sun_or_shade)	// Write while loop that reads records from file.
		{
			cout << flowerName << " grows in the " << sun_or_shade << endl;
		}

		// Print flower name
	}
   fin.close(); 	
   return 0;
  } // End of main function 
Topic archived. No new replies allowed.