Input file opens but nothing is saved. Help!

Hello out there! I am having trouble inputting a text file into my code. The text file I want to use looks like this:

A 1 5
B 2 5
C 4 5
D 20 5
E 22 5
F 24 5
G 26 5
H 28 5
I 30 5
J 88 3

So all of these numbers mean something to me obviously but my problem is I have a class that uses a function that reads in the file in a function below called readInCustomers().
When I debug my code and step into this function, the function will open the file according to the debugger but nothing is being saved or pushed into myQueue. Each line in the file represents data for customer a, b, etc.

Can anyone see the issue as to why my infile data won't save into my structs? Any help would be greatly appreciated!
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//Bank.h 

struct Customer
{
    int waitTime;
    int arrivalTime;
    int transTime;
    char name;
    int departTime;
};

class Bank {

private:
    int itemCount;  // # of elements in Queue
    std::queue<Customer>myQueue;
    bool tellerAvailable;
    int clock; //simulates time

public:
//    Default Constructor
    Bank();

//    Checks if Queue is empty
    bool isEmpty();

//    Size of Queue
    void size();

//    Inserts element at end of Queue
    void readInCustomers();

//Bank.cpp file 

#include "Bank.h"
#include <queue>
#include <fstream>
#include <iostream>
using namespace std;

void Bank::readInCustomers()
{
    Customer c;
//      Here we insert the input file.
//      Open file
      ifstream infile ("inputFile.txt");
      infile.open("inputFile.txt");
//      If file opens
      if (infile.is_open())
      {
           while(!infile.eof())    //While not end of file
           {
//     Grab each line that contains:
//    Letter, time, timeInterval in each line
            infile >> c.name;
            infile >> c.arrivalTime;
            infile >> c.transTime;
            myQueue.push(c);
            itemCount++;
           }
      }
      //If file does not open
       else
       {
           cout << "Error. File did not open\n";
       }
//       close file
       infile.close();

}
void Bank::startSimulation()
{
    readInCustomers();  //Queue should be full now
    if (tellerAvailable == true)
//        Look at queue and pop out customer which makes teller not available
        myQueue.front();    //customer at front of line
        myQueue.front().name;

}

Last edited on
> the function will open the file according to the debugger
> but nothing is eing saved or pushed into myQueue
¿how did you check that?


> if (tellerAvailable == true)
by the code that you showed, `tellerAvailable' is uninitialised.
show enough code to reproduce your problem.

also, ¿why are you comparing a boolean?


1
2
      ifstream infile ("inputFile.txt");
      infile.open("inputFile.txt");

http://www.cplusplus.com/reference/fstream/ifstream/open/
If the stream is already associated with a file (i.e., it is already open), calling this function fails.
(...)
In case of failure, failbit is set.
you already opened the file in the constructor, don't try to open it twice.
Last edited on
Hello Marcos8701,

As ne555 said show enough code to reproduce your problem. What you have posted is not even complete to compile.

In "bank.h", for the struct, you should initialize the variables so that you are not working with garbage values.

This should work for you:
1
2
3
4
5
6
7
8
struct Customer
{
	int waitTime{};
	int arrivalTime{};
	int transTime{};
	char name{};
	int departTime{};
};


The empty {}s will set the variables to zero, available form C++11 on. If this is a problem you can use " = 0" and let me know what IDE you are using I might be able to help you change the IDE.

The class is missing some forward declarations and also the closing "}:" at the end of the class. You have forward declared the default ctor, but you also need to forward declare the default dtor. Once you say there is a default ctor you also have to say that there is a default dtor. Once you declare a default ctor the compiler does provide the default ctor or dtor. This also happens when you define an overloaded ctor. The compiler does not provide the default ctor or dtor. This is left up to you.

You forward declare the functions "isEmpty" and "size", but never provide the functions. This is not a problem and does nor cause any errors at compile time, but it is not complete.

You are missing the forward declaration for "startSimulation" Nor a problem here, but it is in the "Bank.cpp" file.

In the "Bank.cpp" file:
You have:
1
2
3
4
5
#include "Bank.h"
#include <queue>
#include <fstream>
#include <iostream>
using namespace std;

Some have said the order should not make any difference, but sometimes I find that it does. I found that this makes a big difference:
1
2
3
4
5
6
7
#include <queue>
#include <fstream>
#include <iostream>

#include "Bank.h"

using namespace std;  // <--- Best not to use. 

By putting "Bank.h" last the previous header files are compiled into the program first thus covering anything that would be used in the header file.

Since you have forward declared the default ctor and detor you need to provide these functions in the ".cpp" file.

The ctor should be something like this:
1
2
3
4
5
6
Bank::Bank()
{
	itemCount = 0;  // # of elements in Queue
	tellerAvailable = 0;
	clock = 0; //simulates time
}

Here "itemCount is a good example. Left uninitialized it will contain a garbage value this is usually "-858993460" on my computer for an int. Just adding "1" to this would leave you with "-858993450". Not what you want.

A default dtor would be Bank::~Bank() {} unless you decide to put something between the {}s.

Leaving out the function definitions for "isEmpty" and "size" that is OK since they are never used anywhere yet.

In the "readInCustomers" function, and as ne555has pointed out, ifstream infile ("inputFile.txt");, The first part definde the file stream for "infile". The second part "("inputFile.txt")" provides the file name to use. All together this will create "infile" and open the file at the same time. This is the shortest way to do this and most often used.

The next line infile.open("inputFile.txt"); is trying to open a file stream that is already open, so it fails. This causes this line to fail, so when you get to the if statement the condition will evaluate to false and you end up at the else part even if the file stream did open with the first line.

The if/else statements work and your code is short enough not to complain about, but a better if statement would be:
1
2
3
4
5
if (!infile)
{
	std::cout << "\n  Error. File did not open\n" << std::endl;
	/*return 1;*/  exit(1);  // if not in "main"
}

Zero means a normal return or exit and any number greater than zero means that there is a problem. The reason that you return or exit is because there is no point in continuing with a file stream that is not open and usable.

In the while(!infile.eof()). This does not work the way you think it does. By the time it finds that the "eof' bit has been set you have processed the last read twice and left 'index" one number higher than it should be and that is not what you want.

A more common way of writing the while condition is: while (infile >> c.name >> c.arrivalTime >> c.transTime). This way when you try to read past "eof" the "eof" bit is set and the while condition becomes false thus ending the while loop.

Since the function void Bank::startSimulation() was not forward declared in the header file none of this code would work.

Once I fixed the problems it worked.

I did have to create a "main" function to get things started. This may not be what you have. I do not know because you failed to include this with you other code.

One thing that did occur to me late is the use of a header guard. It would be something like this:
1
2
3
4
5
6
#ifndef BANK_H
#define BANK_H

// your code here.

#endif // !BANK_H 

The name, "BAND_H", can be anything you like, but usually looks something like this and in all caps.

Hope that helps,

Andy
Thank you both for recognizing one of my problems. I switched my if statement to a do
1
2
3
4
5
6
7
8
9
10
11
12
13
14
      ifstream infile ("inputFile.txt");

      if (infile.is_open())
      {
           do {
//     Grab each line that contains:
//    Letter, time, timeInterval in each line
            infile >> c.name;
            infile >> c.arrivalTime;
            infile >> c.transTime;
            myQueue.push(c);
            itemCount++;
           } while(!infile.eof());
      }


And now my data is being fed into my variables!! Special thanks to you Andy for taking the extra time to run my code and giving me pointers on writing cleaner code. Cheers!
Last edited on
Topic archived. No new replies allowed.