Searching in a file containing class object not working properly!

http://ideone.com/e.js/4owvFH
(Please follow the link to the program code)

Adding is working perfectly but when I search for a particular record using ID, the function works only for the ID of the first record I had entered.

For instance, if the ID of the first record I enetered is 68 and that for the second is 78, when I search using 78 "ID not found!" is displayed. When I search using 68, it shows the information but the same information is displayed twice.

What is going wrong and how can I fix this?
There are a lot of things which make me feel uneasy in this code, the first of which is the use of global variables
1
2
char ch, c, cs;
int id;
and
 
docnur dn;

so the first thing I'd do is remove all of those. Some can be declared locally inside the function where it is used, while the docnur can be declared in main().

As for the problems reading from the file, the root of that is the loop:
 
    while (!fin.eof())

Don't loop on eof(), it is wrong for a number of reasons. Instead, put the file input statement itself in the while condition.

Then the code might look like this:
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
void docnur::dnview()
{
    char f = 'f';
    int id;
    cout << "\n\nEnter ID of the staff member to be viewed:";      cin >> id;
    
    ifstream fin("Staff.txt");
    
    if (fin.fail())
    {
        cout << "\n";
        for (int x=0; x<40; x++)
            cout << "-";
        cout << "\n";
        
        for (int x=0; x<10; x++)
        cout << "-";
        cout << "File Empty";
        for (int x=0; x<10; x++)
            cout << "-";
        
        return;
    }
    
    while ( fin.read((char *) this, sizeof(docnur)) )
    {   
        if (id == dnid)
        {
            f ='t';
            cout << "\nStaff member ID:"<<dnid;
            cout << "\nName: ";
            if ('d'== nd)      cout<<"Dr. "   << name;
            if ('n'==nd)       cout<<"Nurse " << name;
            cout << "\nAge:"     << age;
            cout << "\nGender:"  << gender;
            cout << "\nPhone number:" << phoneno;
            cout << "\nExperience:"   << exp;
            cout << "\nSalary per month:" << salary;
            cout << "\nDepartment in which admitted:" << dept;
        }
    }

    if (f == 'f')
    {
        cout << "\n";
        for (int A=0; A<30; A++)
            cout << "-";
        cout << "ID not found!!";
        for (int A=0; A<30; A++)
            cout << "-";
    }

}

Notice as well as the while loop, the read statement has been changed so it no longer uses the external variable dn.
old:
1
2
3
    while (!fin.eof())
    {
        fin.read((char *)&dn, sizeof(dn));

new:
1
2
    while ( fin.read((char *) this, sizeof(docnur)) )
    {   

Last edited on
Thanks!
But can you please tell me what is "this"? Is it a keyword?
Yes, this is a C++ keyword. It is a pointer which holds the memory address of the current object.
I tried with the code that you suggested but it still doesn't work!!
My head's literally blasting thinking of what the hell's wrong?????
Could you elaborate on "it still doesn't work". What exactly happens when you try it?
Why do you use fin.read and fout.write when the file is in text mode ?
read and write are normally used for binary files.
It also would help if you could some sample data
The same problem of
ID not found!!


Your code has stopped the multiple display of the same data though.
Looking at the logic of your code, that means that either:

a) your while loop doesn't even iterate once, or
b) for every iteration of your loop, the condition (id == dnid) is false.

The most productive thing you can do at this point is to step through your code in a debugger. This will allow you to see which of these things is happening, and will allow you to examine the values of your variables to see what's in them, and why this might be happening.

Just as an aside, it looks as though you're using f to store a character that can either be 'f' for false, or 't' for true. Is there any reason you can't just use a bool, which is designed specifically to store a true/false value?
Last edited on
I'd love to do that
But how do you do that "step through my code in a debugger" thing?
Well that would depend on which debugger you're actually using. What IDE are you using? Does it include a debugger?
I'm using codelite IDE. And MinGW compiler for compilation.
> void docnur::dnview()
One single element has the responsibility to search an entire file, comparing ids of other elements while overwriting its own status.
¿Does that sound fine to you?

You need to differentiate an element from a collection, and what responsibilities each one has.

Same may be said about void docnur::dadd()


> The same problem of
> ID not found!!
¿Can you open the file through an editor to see the registers?


> But how do you do that "step through my code in a debugger" thing?
> I'm using codelite IDE. And MinGW compiler for compilation.
http://codelite.org/LiteEditor/Debugging
But a breakpoint on line 27 of Chervil's code, print *this and check the values.
If you could provide a complete testcase (enough code to reproduce your program and input examples) we may help you further.



PS: ¿why is dadd() recursive instead of a simple loop?
Last edited on
Maybe something "got lost in translation". The code I posted previously was something which I had actually tested as part of a complete program. So I can think of several possibilities, such as your code differs from mine in some way (almost certainly), or the data file you are using differs from mine (I used the program itself to create the file), or there is something about the way in which you are running the program, or the environment, which make it behave differently.

For now, could you post the latest version of the complete code which you have, so that I or some others can take another look.

I tried the debugger (thanks to @ne555).
When the code reaches the while (fin.read((char *)this, sizeof(docnur))), the debugger shows
GDB ERROR: "Couldn't find method std::ifstream::read"
.
What does that mean?
And how to fix it?
Also the dnid is fixed at the ID of the first record I ad entered.
Last edited on
I finally found the mistake!!
The loop for displaying
ID not found!!
was inside the while loop.
That's why the dnid was always only the one for the first one, it never went to the second record as the read statement never read the second record at all. Putting the loop
ID not found!!
outside the while loop fixed it.

Thanks to all! Especially @MikeyBoy and @ne555. I figured this out using the debugger!
You're welcome - glad it worked out.
Topic archived. No new replies allowed.