Hi everyone at daniweb!

First off I want to say thanks for starting this awesome homepage, though googleing ive found many clues and answers in here for my projects, things that were left undocumented or just poorly explained by those books that ive used.

But now, onto the issue!
What I'm trying to do is to create a tool which processes/reads a user database where I then store the result into another file.
Explaining this straight off and step-by-step is somewhat complicated for me, so to give you a bigger understanding of the issue I'm going post the structure of my "users.txt" database, and then explain how I wish to process it.

So my users.txt which contains information looks somewhat like this:
(txt tag didn't display the text correctly (it removed all the whitespaces and put everything on a single line- that's why i'm using code tag))

::::::::
Jenny
::::::::
Female
24 years old
Married
School teacher

::::::::
Jake
::::::::
17 years old
Student
Male
Single
Dog owner

::::::::
Katie
::::::::
Police officer
Single
32 years old
Female
Cat owner

Then what I'd like to do and have searched everywhere for, was to have my program/tool to return a certain result after i give it a specific keyword, for instance at this list, it might be interesting for me to know how many females I have registered and what their names are- So if I were to give the keyword "female" the program should process the stream, find the line "female" and then "rewind"/step back till it reaches the name of the woman, like, go back till "::::::" is found then take another step back and read the whole line and store this to a newly created file called female.txt, then continue looking though the file till it reaches EOF.
Also I'd like the tool to be able to update our female.txt file but in that way it wouldn't create duplicates of an already existing name, like comparing strings but- and i might be asking for the impossible now, in direct access with the file streams, somethings like if (usersIn.name == usersOut.name) cout << "duplicate entry! ignoring name!" << endl;

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <conio.h>
using namespace std;

int main(void)
{
   ifstream inUsers("users.txt", ios::in);
   if (!inUsers)
   {
      cout << "The file wasn't found!" << endl;
      // we _must_ have a users.txt in order to run the program properly
      exit(1);
   }

   else
   {
       cout << "File found!" << endl;
   }

   // This part may look weird and require some explaining, so..
   // First, if the file doesn't exist, I wish to generate a new one with NO duplicate entry check
   // Second, if the file DOES exist, then I wish to read the file and compare strings

   ifstream outFemales("females.txt", ios::in);
   if(!outFemales)
   {
       cout << "The file wasn't found!" << endl;
       outFemales.close();

       cout << "We shall now generate the file for writing!" << endl;
       ofstream outFemales("females.txt",ios::app);
       // <code that reads though users.txt and stores the names to females.txt goes here>
   }

   else
   {
       cout << "The file was found!" << endl;
       outFemales.close();

       cout << "We shall now re-open the file for writing!" << endl;
       ofstream outFemales("females.txt",ios::in|ios::app);
       // <code that compare filedata with users.txt and stores new names goes here>
   }

   getch();
   return 0;

}

Basically that's where I'm at right now and I'd like to let you know that it's not a case like "I don't understand anythings! please please please do this for me!" because it simply wouldn't benefit me, I'm trying to learn as much as possible so that I hopefully in the future can develop both good games and useful applications but ive looked everywhere and I haven't found anything that describes or any book which explains anythings close to what I'm trying to achieve, so- that's why I'm turning here, hopefully someone of you wise men and/or women can shed some light on this matter and help me understand what ive missed, or if you know any good site or book which has the documentation i'm looking for, I'd love it if you could share it D: :)

Edited 6 Years Ago by usagi: n/a

I can't edit now so imma bump instead (*crosses fingers and hopes it's ok*).
If someone could just give an example how I can directly compare data from two files with eachothers or/and how I can go backwards in a stream after ive entered my "keyword", like

{ while(in >> myword) { process_text; }
// < code that allows be to go backwards >
}

- it would be very appreciated.

Unless you have to constantly read/write from the file as a requirement for the project, I wouldn't do that. I would load all the data (Since these files are not large) into a data structure of your choice (Anything from a simple array of structures to a linked list, binary tree etc.). After you have loaded the data, you can search everything in memory which is much fast and usually easier.

I'm with you and ive considered that method since it's the only way I currently know how, however for this task and to work with direct access as it would be an valuable learning process for me, so atm it's not really a matter which one is fastest or best but rather finding alternative methods/routes, so that I can work and experiment with it, and one day when it's a better choice, build software with it.

istream has a method called seekp(). This will allow you to "jump" around the file. For example, you can read from the file then, for searching purposes, set the file pointer back to the beginning of the file and search again. You can also set the pointer to stay at the current position and go to the eof.

Edited 6 Years Ago by hag++: n/a

istream has a method called seekp(). This will allow you to "jump" around the file. For example, you can read from the file then, for searching purposes, set the file pointer back to the beginning of the file and search again. You can also set the pointer to stay at the current position and go to the eof.

That's the thing, even if I mark a certain location the program wont know what to connect with it, for instance it finds the line "Female" and restarts to look for name, how will it now be able to know what name to stop on? the layout for a girl is basically the same as a man- so basically, I _must_ reverse scan/search/look(i--/n--/etc) from the point I found my keyword to the point where it gives me my answer based on a somewhat simple rule.

Pulling stuff from my mind i think the case using for would look somethings like "for(file.good(); getline(???) != ":"; location--)",and bout the .eof- though ive seen a lot of posts saying "avoid .eof" as it wont do what i expect it to do, not certain if applies in my case not.

Edited 6 Years Ago by usagi: n/a

When you read "::::::::" you know the next line is a name, followed by another "::::::::". Then read the data up to the blank line or "::::::::" saving each line in an array. Then look through the array for your keyword.

Continue by reading the next name information.

When you read "::::::::" you know the next line is a name, followed by another "::::::::". Then read the data up to the blank line or "::::::::" saving each line in an array. Then look through the array for your keyword.

Continue by reading the next name information.

This was pretty much my planB ( store name -> look for keyword -> if keyword not found before empty line -> drop name -> repeat till EOF ) however it requires a few more instructions/code than my initial plan, that's why I wanted to avoid it- I had rather hoped that it was a case where i just had missed somethings, but yea I guess I can live with it.

Tnx for the input :)

A couple of google days later ive finally managed to get somewhere, unfortunately there's several gaps and the do-whiles doesn't work as intended then add stress and concentration issues and you have a head that's ready to pop.

So please ,_, if there's someone who has time and sees what ive done wrong, please help little me get on the right track.

#include <iostream>
#include <fstream>
#include <conio.h>
#include <cstdlib>
using namespace std;

int main(void)
{
   string sMan;
   ifstream inUsers("users.txt",ios::in);

   if (!inUsers)
   {
      // Critical file wasn't found, bailing out!
      cout << "The file wasn't found!" << endl;
      exit(1);
   }

   while(getline(inUsers,sMan))
   {
      if(sMan=="Female")
      {
         // Step back till sign '=' and sign(pos-1) is '\n', this should place is just behind the persons name
         do inUsers.seekg(-1,ios::cur);
            while( inUsers.peek() != '=' && (inUsers.seekg(-1,ios::cur) && inUsers.peek() != '\n'));

         // Now, if we go back another line we should be infront of the Womans name.
         do inUsers.seekg(-1,ios::cur);
            while( inUsers.peek() != '\n');

         // Doing a check for females.txt
         ifstream outFemales("females.txt", ios::in);
         if(!outFemales)
         {
            // No file found
            outFemales.close();

            // Generating and opening the file for writing
            ofstream outFemales("females.txt",ios::app);
            // TODO/HELP: Store name of Woman (outFemales >> getline ..inUsers, ios::cur..)
          }

          else
          {
             // File found - closing..
             outFemales.close();

             // Reopening the file for reading AND writing
             ofstream outFemales("females.txt",ios::in|ios::app);
             // TODO/HELP: Compare any found string in females.txt with the users.txt extracted name
           }

         // DEBUG // cout << sMan << endl;
         cout << inUsers.peek() << endl;
      }
      // DEBUG
      else cout<<"ELSE:::: "<<sMan<<endl;
   }
   getch();
   return 0;
}

Edited 6 Years Ago by usagi: n/a

This article has been dead for over six months. Start a new discussion instead.