Searching in a file containing class object not working properly!

Nov 23, 2016 at 9:16am
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?
Nov 23, 2016 at 12:10pm
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 Nov 23, 2016 at 12:13pm
Nov 23, 2016 at 12:13pm
Thanks!
But can you please tell me what is "this"? Is it a keyword?
Nov 23, 2016 at 12:35pm
Yes, this is a C++ keyword. It is a pointer which holds the memory address of the current object.
Nov 23, 2016 at 4:05pm
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?????
Nov 23, 2016 at 4:11pm
Could you elaborate on "it still doesn't work". What exactly happens when you try it?
Nov 23, 2016 at 4:38pm
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
Nov 23, 2016 at 4:56pm
The same problem of
ID not found!!


Your code has stopped the multiple display of the same data though.
Nov 23, 2016 at 5:22pm
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 Nov 23, 2016 at 5:25pm
Nov 24, 2016 at 10:51am
I'd love to do that
But how do you do that "step through my code in a debugger" thing?
Nov 24, 2016 at 11:49am
Well that would depend on which debugger you're actually using. What IDE are you using? Does it include a debugger?
Nov 24, 2016 at 12:08pm
I'm using codelite IDE. And MinGW compiler for compilation.
Nov 24, 2016 at 1:18pm
> 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 Nov 24, 2016 at 1:20pm
Nov 24, 2016 at 1:22pm
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.

Nov 24, 2016 at 5:37pm
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 Nov 24, 2016 at 5:53pm
Nov 25, 2016 at 7:36am
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!
Nov 25, 2016 at 10:59am
You're welcome - glad it worked out.
Topic archived. No new replies allowed.