File IN/OUT getline problems

Hey Guys,

I'm working on an assignment from school and I am stumped. I'm not a C++ newb per say but I don't have alot of experience with dealing with read/write with files. Case 3 is my first issue, when I run the report it prints the employee info fine, but if I go to run it again it prints nothing.

Case 2 is also got me hitting a brick wall, but we can deal with one thing at a time.

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
82
83
84
85
86
87
88
89
90
91
92
93
int _tmain(int argc, _TCHAR* argv[])
{
	
	bool loop = true;
	int choice = 0;
	ofstream employeeFileOUT("employee.txt", ios_base::app);
	ifstream employeeFileIN("employee.txt", ios_base::app);
	string firstName;
	string lastName;
	string address;
	string position;
	string line;
	double salary;
	string nameSearch;

	

	while(loop = true)
	{

		//employeeFileIN.open();
		//employeeFileOUT.open();

		cout	<< "1. Enter New Employee" << endl
				<< "2. Find Employee" << endl
				<< "3. Print Report" << endl;

		cin >> choice;
		cin.clear();
		cin.ignore(INT_MAX, '\n');

		switch(choice)
		{
			case 1:
				cout <<"Enter employee's first name: ";
				getline(cin,firstName);
				cout <<"Enter employee's last name: ";
				getline(cin,lastName);
				cout <<"Enter Employee's Address: ";
				getline(cin,address);
				cout <<"Enter Employee's Position: ";
				getline(cin,position);
				cout <<"Enter Employee's Salary: ";
				cin >> salary;

employeeFileOUT << firstName << ';' << lastName << ';' << address << ';' << position << ';' << salary <<endl;

				break;
			case 2: //Work in progress
				/*
				cout <<"Enter Employee's Last Name: ";
				cin >> nameSearch;
				while(getline(employeeFileIN, line))
				{	
					string word;
					stringstream stream(line);
					while( getline(stream, word, ';') )
					{
						cout << word << " ";
					}
					cout << '\n';
				}

				*/

				break;
			case 3:
//When I run case 3 it works fine, but when I run it again it doesn't print anything.
				while(getline(employeeFileIN, line))
				{	
					string word;
					stringstream stream(line);
					while( getline(stream, word, ';') )
					{
						cout << word << " ";
					}
					cout << '\n';
				}
				
				break;
			case 0:
				loop = false;
				break;
		}
		employeeFileIN.clear();
		employeeFileIN.close();
		employeeFileOUT.close();
	}

	
        system("pause");
	return 0;
}


Thank you for your time and help!

-Dak
Last edited on
I suspect the problem with case 3 not working more than once is that after running once, you've reached the end of the file, so when you try to go through again you're already at the end and finish immediately. You should try to find a way to start at the beginning again... (hint: you'll be manipulating the file pointer, so look for functions that do that)
A minor problem at line 18, while(loop = true) should use the == comparison operator, not the = assignment operator.

This is quite an interesting program. If you want the "report" option to reflect the changes made in the "enter employee" option, there are a few things you might need to do.

One is to close and re-open the two files each time around the loop. Another is to keep the output file open, but use the flush() function at the end of adding a new employee. The report file won't reflect the changes unless it's closed and opened again.

Another approach is to use a single file (which is what it is, in reality) for both input and output, and open it with the options ios_base::app | ios_base::in | ios_base::out or something like that. By the way, ios_base::app doesn't make much sense for an ifstream (input only).

You will as suggested have to reset the file position to read from the beginning when producing the report. The use of clear() may also be required after reading to the end of the file, or after a possible write error (maybe in the case of bad user input).
You two guys are awesome.

@Zhuge, now that you say it, that makes perfect sense!

@Chervil, I am completely new to fstream operations so I was kinda just throwing stuff out there.

I get mostly what you are saying and will see about updating them to use the correct format. Besides just searching google is there a good place for an in-depth review of fstream?

Thanks again all! I'll come back with the progress and probably have one or two more questions.

-DaK
There is a section in this site's tutorial which may help, http://www.cplusplus.com/doc/tutorial/files/
There's also the relevant sections in the reference section. fstream, ifstream and oftream are covered here: http://www.cplusplus.com/reference/iostream/

Basically, the capabilities give you a set of tools, the trick is to know which tool to use for which purpose. Largely, you can only learn properly by actually using them.

If you can run your program with a debugger, I'd recommend monitoring the state of the .good() flag. When things don't work as you expect, it's often because some previous action has set one of the condition flags.

If you don't have a debugger, it may be worth adding temporary debugging messages at key points in your program (just before and/or just after using the stream), to display the state of the stream: good() and possibly also bad(), fail() and eof().
Last edited on
Quick update, case 3 works perfectly! I also have a much better understanding of fstream (though I still need more time playing around with it to fully get it all).

I'm going to attempt case 2, though it's search function through the string confuses me a bit.

More updates/questions to come I'm sure.

-Dak
I am so close to finishing, but I am having an error with this section:

for(int x=0; x <= (int)line.length(); x++)
{
cout << "test2" <<endl;
if(line[x] != ';')
{
tempWord += line[x];
}

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
case 2:
				
				cout <<"Enter Employee's Last Name: ";
				cin >> nameSearch;
				employeeFileIN.open("employee.txt",ios_base::in);
				line = "";
				matches = 0;

				while(getline(employeeFileIN, line))
				{	
					cout << "test1" <<endl;
					for(int x=0; x <= (int)line.length(); x++)
					{
						cout << "test2" <<endl;
						if(line[x] != ';')
						{
							tempWord += line[x];
						}
						else
						{
							varNum++;
							tempWord = "";
							switch(varNum)
							{
								case 1:
									tempFirstName = tempWord;
									tempWord = "";
								case 2:
									tempLastName = tempWord;
									tempWord = "";
								case 3:
									tempAddress = tempWord;
									tempWord = "";
								case 4:
									tempPosition = tempWord;
									tempWord = "";
								case 5:
									tempSalary = tempWord;
									tempWord = "";
							}
						}
					}
					if(lastName == nameSearch)
					{
						search[result] = tempFirstName + tempLastName + tempAddress + tempPosition + tempSalary;
						matches++;
					}	
				}
					cout << "Employee's with last name: " << nameSearch <<endl;
					for(int y = 0; y <= matches; y++)
					{
						cout << search[y];
					}
				break;



Any thoughts or helpful hints?

Thank you!

-Dak
What sort of error? A compiler error, program crash, logic error or incorrect results?
Line 12 of your case 2:, what is (int)line.length() supposed to do? I've never seen a function call like that. I understand .length is a member function of the line class, but (int) at the beginning? Not sure what that's supposed to do, but I'm no expert by any means, especially with classes and such, so if you know it to be correct please disregard. :)

If you are simply calling the length member of the string class, which it looks like, it'll return the length as an int anyway (or at least, an unsigned integral type according to the reference for it) so you could just use
for (int x=0; x <= line.length(); x++)
Last edited on
@Chervil. "Debug Assertion Failed!" It doesn't show up as an error in the error list. So I guess a program crash. I did some testing and it seems the problem is how x is compared to the length of the string.

@Raezzor. I am attempting to cast line.length to an int (I don't know how casting works in C++, but that is how it works in C#). I don't know what the problem is but I figured it might be due to it being an unsigned int.

-Dak
Hmm ya, I don't think you have to cast it. According to the string::length reference here.

http://www.cplusplus.com/reference/string/string/length/
Fair. I don't know what the problem is then. I'll keep combing through it. Let me know if anyone sees it!

Thanks!

-Dak
No problem. Like I said I'm no expert either, so you may be right. But I've used .length myself in test expressions and never had to cast it, but then I may have just gotten lucky. :)
Hey Dak,

From what I've read on the net, it maybe something to do with your file opening being NULL. Add in a code to check if the file is open or not before going through ur code.

Also, your case 2 code seems really weird...

There's nothing declared for search[] and result.

Your switch code is missing breaks();.

Your setting tempWord = ""; before going into the switch, and then, tempFirstName = tempWord;

I'm guessing you've declared the missing search[] and result some where else?
Last edited on
for(int x=0; x <= (int)line.length(); x++)

if x == line.length(), then x is an invalid index, so you need to change the conditional.

for ( int x =0; x < line.length(); ++x )
Topic archived. No new replies allowed.