Record deleting

I Wrote the code that takes a roll no and deletes the data of that roll no but there is a little problem ... when i copy data from one file to another removing the roll no that is given and then copy it back to original file the las record is shown twice....plzzzz help

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
  void delete_student(int a)
{
			fstream x( "C:/Users/MR_Salman/Desktop/new.txt",ios::out|ios::in|ios::binary );
			fstream f( "C:/Users/MR_Salman/Desktop/new2.txt",ios::out|ios::in|ios::binary );
			ostringstream ot ;
			ot << a ;
			string rem = ot.str();
			while(x.good())
			{
			if (x.eof())
			break ;
			string s ;
			getline ( x,s,'\n' ) ;
			//f << s << "\n" ;
			if ( s.find(rem,0) )
			f << s << "\n" ;
			
			}
			x.close();
			f.close();
			x.open("C:/Users/MR_Salman/Desktop/new.txt",ios::out|ios::in|ios::binary) ;
			f.open("C:/Users/MR_Salman/Desktop/new2.txt",ios::out|ios::in|ios::binary);
			while(f.good())
			{
				if (f.eof())
				break ;
				string k ;
				getline(f,k) ;
				x << k << "\n" ;
			
			}
			x.close();
			f.close();
}
the las record is shown twice
most likely caused by either getline() at line 13 or at line 28 being used in subsequent processing without ever testing whether or not the getline in fact succeeded.

After each input operation, you must test that the file status is good() (or that it is not fail() ), before going on to use that data.
would you please give an example???? i dont get it ....rather i used but didn't work....
Well, I didn't test your code, so my idea was a guess at a likely explanation.
For example here,
1
2
3
    getline ( x,s,'\n' ) ;
			
    if ( s.find(rem,0) ) // We don't know whether previous getline failed 


But commonly, instead of this, which tests both x.good() and x.eof() but still misses a possible failed getline:
1
2
3
4
5
6
7
8
9
10
11
while (x.good())
{
    if (x.eof())
        break ;
        
    string s ;
    getline ( x,s,'\n' ) ;
    
    if ( s.find(rem,0) )
        f << s << "\n" ;
}


replace that with the following:
1
2
3
4
5
6
7
string s ;
    
while ( getline ( x, s, '\n' ) )
{
    if ( s.find(rem,0) )
        f << s << "\n" ;
}

Of course, your code has a second while loop which has similar flaws. That should also be changed - or in fact simplified, the code is over-complex, when you might instead just do a file remove and file rename instead of the second block of processing.
Also in the following snippet:
if ( s.find(rem,0) )

You probably should look up the string find() function. You should actually be testing against a value, remember if this function doesn't find the value it doesn't return 0, it returns std::string::npos.

Another thing, you opened your files in binary mode so you probably shouldn't be using getline(). Normally when you open the file in binary mode you use the unformatted input and output (read/write).

And since you are reusing your streams you need to be careful. Just closing and reopening the files will not reset the stream error states. You need to implicitly clear these errors before reusing the stream.

Yes Brothers That Realy Solved My Problem But i Dont Get That
1)Why should i not use getline with binary files ??
2)Can i write the whole code in just one loop to get it working ???
3)And Chervil You mentioned flaws in loops and i do agree that but plzzz tell me what those flaws are and how to get rid of them ????Plzzzzzzz And Thanks my code is working Fine ......
And Chervil You mentioned flaws in loops and i do agree that but plzzz tell me what those flaws are and how to get rid of them ????

I already explained:
After each input operation, you must test that the file status is good() (or that it is not fail() ), before going on to use that data.


I gave example code above. I'm not sure if you are asking about something else.
Here was one way which I considered:
1
2
const char nupdate[] = "C:/Users/MR_Salman/Desktop/new.txt";
const char ntemp[]   = "C:/Users/MR_Salman/Desktop/temporary.txt";


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
void delete_student(int a)
{
    ifstream fin( nupdate );
    ofstream ftemp( ntemp);
    
    string line;
    int num;
    
    while (getline(fin,line))
    {
        istringstream ss(line);
        
        if ( !(ss >> num && num == a) )
            ftemp << line << '\n';
    }
    
    ftemp.close();    
    fin.close();   
    
    if (fin.eof() && ftemp.good())
    {
        remove ( nupdate );
        rename ( ntemp, nupdate );  
    }         
}
Thanks To All Of You Bro ....
1)Why should i not use getline with binary files ??

Let me first answer this with a question: Why did you open the file in binary mode?

Normally binary mode is used for unformatted input and output, usually using the read()/write() functions.

You normally use text mode when dealing with formatted input and output, cin/cout, getline(), etc.

Topic archived. No new replies allowed.