0

How do I return the location of an item in a .dat file?

in the search() function I attempting to find an item in the fractions.dat file and return it to the user. However the function always returns -2 (the value that the variable being returned was initialized to originally).

The if statement executes, but it appears that file.read(...) isn't setting cur to anything.

#include <iostream>
#include <fstream>

using namespace std;

struct Fraction
{
    int num, den;
};

int search(fstream& file, Fraction* f);
int menu();
void proccessChoice(int i);
Fraction* readFrac();

Fraction* fracs[100];
int index;
string fileName = "fractions.dat";
fstream file(fileName,  ios::in | ios::out | ios::binary);

int main()
{
    if (!file)
    {
        cout << "Error opening file. Program aborting.\n";
        system("pause");
        exit(1);
    }
    int choice;
    do
    {
        choice = menu();
        proccessChoice(choice);
    } while(choice != 3);

    system("pause");
    return 0;
}


int menu()
{
    int c;
    cout << "1.Enter new fraction" << endl;
    cout << "2.Find fraction location" << endl;
    cout << "3.Quit" << endl;
    cin >> c;
    return c;
}

void proccessChoice(int i)
{
    switch(i)
    {
    case 1:
        {
            cout << "Please enter a fraction to be stored: ";
            fracs[index] = readFrac();
            file.write(reinterpret_cast<char*>(fracs[index]), sizeof(Fraction));
            /*cout << fracs[index]->num << "/" << fracs[index]->den ;*/
            index++;
        }
            break;
    case 2:
        {
            cout << "Please enter a fraction to find: ";
            Fraction* fToFind = readFrac();
            int i = search(file, fToFind);
            cout << "The fraction is at position: "<< i << endl;
        }
            break;
    }
}
int search(fstream& file, Fraction* f)
{
    Fraction* cur = new Fraction();
    int pos = -2;
    if (!file)
    {
        cout << "Error opening file. Program aborting.\n";
        system("pause");
        exit(1);
    }
    while(!file.eof())
    {
        file.read(reinterpret_cast<char *>(cur), sizeof(Fraction));
        if((cur->num == f->num) && (cur->den == f->den))
        {
            cout << "\nFrac found!" << cur->num << "/" << cur->num<<endl;
            pos = file.tellg();
            return pos;
        }
    }
    return pos;
}

Fraction* readFrac()
{
    Fraction* f = new Fraction();
    char slash;
    cin >> f->num >> slash >> f->den;
    return f;
}
Zzz
  • 2,927
  • 5
  • 36
  • 58
  • is the `frac found` output appearing? – Karthik T Dec 06 '12 at 06:16
  • Also typically doing `while(!file.eof())` is not good, as explained better [here](http://stackoverflow.com/a/21656/1520364) – Karthik T Dec 06 '12 at 06:20
  • Well then, looks like either the while or the if (my bets are on the if) might be failing. Why dont you put a print outside the if with both the fractions and check why it is not matching – Karthik T Dec 06 '12 at 06:28
  • Is this your real code? fstream doesn't have a constructor that takes a string, only a char* so this didn't compile for me. Also, opening the file like that as a global variable seems like a bad idea. – Retired Ninja Dec 06 '12 at 06:33
  • @RetiredNinja Its real code and it compiles. I am using VS2010. – Zzz Dec 06 '12 at 06:34
  • @KarthikT I have debugged this code and the if statement executes but cur isn't set to anything. – Zzz Dec 06 '12 at 06:35
  • can you try with `operator<<` and `operator>>` overloads for `Fraction` rather than `read()` and `write()`? – Karthik T Dec 06 '12 at 06:42

1 Answers1

2

You're not starting the search from the beginning of the file. You need:

file.seekg( 0, std::ios::beg );

Similarly I think you're not appending to the end when writing to the file.

file.seekp( 0, std::ios::end );
acraig5075
  • 10,588
  • 3
  • 31
  • 50