File Operation (patient unresponsive)

The program reads a list of information about DVD's from a file. Im having problems with a function that counts '\n' and every five 'n\' its supposed to increment numDVD. (the idea being that there are five lines of data for each dvd and I want to know how many dvd's are in the file). Unfortunately it compiles fine and returns nothing. Any ideas on why this isn't working? (I have a display function that works just fine so I know that the program can open and read the file)

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
  int countDVD(fstream &infile)
{ 
	int numDVD = 0; //hold the number of dvds
	int newline = 0;  //hold the number of '\n'
	char nL; 
	
	//set read position at begining of file
	infile.seekg(0L, ios::beg);
	
	//Loop to read each character and 
	// search for '\n' till eof
	while(!infile.eof())
	{    
		//set pos to value of current position
		long pos = infile.tellg();
		
		//set read point to current position
		infile.seekg(pos, ios::beg);
		
		// get/copy character at curent position 
		 nL = infile.get();
		
		//test for '\n' and increment the '\n' counter (newline)

		 if (nL == '\n')
		{
			newline++;
		
			//increment numDVD everytime newline hit 5
			if(newline = 5)
			{
			numDVD++;
			newline = 0; 
			}
		}
		
		// move to the next read position
		pos++;
	
	}//end while


	return numDVD;
}
if(newline = 5) You are assigning new value here, not comparing it with one.
oops.. sorry stupid mistake. Fixed it and still nothing. Is there something wrong with the way I'm advancing the read position or looking for the '\n' character? I don't get it.
try
1
2
3
4
5
6
7
8
9
10
11
char nL;
unsigned numDVD = 0; 
unsigned newline = 0;
while (infile.get(nL)) {
    if (nL == '\n') {
        if (++newline == 5) {
            ++numDVD;
            newline = 0;
        }
    }
}

It should work
I tried that too. It looks like it should work but still does not. Here is the rest of my code. Perhaps the problem lies in that. I do appreciate your help so far and any other help you can give. I must be missing something here.


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
// DVDMain.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "DVD.h"

void displayAllLines(fstream &);
unsigned countDVD (fstream &);

int main()
{
	int numDVD;
	fstream dvdFile;
	
	dvdFile.open("c:\\users\\public\\dvd.txt", ios::in|ios::binary);
	
	if(dvdFile)
		{
			while(!dvdFile.eof())
			{
				displayAllLines(dvdFile);
				
			}
		}
		else
		{
			cout<<"ERROR: Cannot open file.\n";
		}

	 numDVD = countDVD(dvdFile);
	
	cout<<numDVD<<endl;

	return 0;
}

void displayAllLines(fstream &infile)
{
	string line;
	
	getline(infile, line, '\n');
	cout<< line<< endl;
}

unsigned countDVD(fstream &infile)
{ 
	
	unsigned numDVD = 0; 
	unsigned newline = 0;  //hold the number of '\n'
	char nL; 
	
	//set read position at begining of file
	infile.seekg(0L, ios::beg);
	
	//Loop to read each character and 
	// search for '\n' till eof
	while(!infile.eof())
	{    
		//set pos to value of current position
		long pos = infile.tellg();
		
		//set read point to current position
		infile.seekg(pos, ios::beg);
		
		while (infile.get(nL)) 
		{
			if (nL == '\n') 
			{
				if (++newline == 5) 
				{
					++numDVD;
					newline = 0;
				}
			}
		}
		pos++;
	}//end while
	
	return numDVD;
}//end function 
By line 19 we can see that dvdFile is in an error state when the loop completes.
It is still in an error state when countDVD is called, so no operations on the stream will succeed.

Also, see:
http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong
ios::binary That is one problem. Do not use binary for text data. It will not give you correct endlines translation (on windows for example it is 2 symbols, text mode will convert them to \n).
Also on line 19 you are reading from file until reading fails. And then passing stream in failed state to your function. Of course condition !infile.eof() will fire right away, because you did not cleared that flag.
Also, do not check for eof() on streams. It will make one read more than needed. For example if you have file:
Hello
following code will get you unexpected output:
1
2
3
4
5
while(!infile.eof()) {
    std::string x;
    infile >> x;
    std::cout << x << std::endl;
}
Hello
Hello

Avoid unnesesary seeking. Tell me what purpose does lines 60 and 63 have. line 76 is essentually is no-op: you are incrementing variable which will be destroyed on the next line.

And actually code I posted should replace outer loop, lines 57 to 77.
Last edited on
Thank you MiiNiPaa! I was definitely going about this the wrong way. Your code worked just fine. I did not know that about [code] ios::binary [\code](I will be reading up on that). I had thought about passing the file stream in the function while it had read to the end of file but I thought that if I reset the read position (lines 60-63) in the function it wouldn't matter. I was wrong. Thank you cire for the link. I will be checking that out and hopefully learning more about the nuances of this wonderful language.
Topic archived. No new replies allowed.