You are here:

C++/problem in reading from a file

Advertisement


Question
I am making a project for my practicals which is a game in which the admin can enter questions and their answers. The player first needs to register with the computer(by choosing an id and password) which is saved in a file. A player then can play the game and gain points by entering the correct answer. A player who had registered earlier with the computer can just relogin again and play. the scores of the players are also maintained.

I am facing a problrm in reading the scores and the questions that i had entered earlier. The question is not properly displayed and it's answer also changes. I am also posting the program code. The program contains no sytatical error and can be run in borland c++.


#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int max=0,p_ans,score=0;
fstream f,g;
class mastermind
{char name[25];
int score;
public:
void store()
{gets(name);
 score=max;
f.open("mastermind.txt",ios::out);
f.write((char*)this,sizeof(this));
f.close();
}
void who_is_the_master()
{clrscr();
 f.open("mastermind.txt",ios::in);
 f.read((char*)this,sizeof(this));
 cout<<"Welcome to 'MASTERMIND HALL OF FAME' \n \n The present mastermind is:";
 puts(name);
 cout<<"\n And the score is"<<score;
 f.close();
}
}master;
class user
{char id[51],pass[11];
int score;
public:
 user()
{strcpy(id,"not assigned");
 strcpy(pass,"not assigned");
 score=0;
}

 void fetch()
 {gets(id);
  gets(pass);
 }

 void writedata()
 {f.open("user.txt",ios::app|ios::ate|ios::out);
  f.seekg(0,ios::end);
  f.write((char*)this, sizeof(this));
  f.close();
 }

 int check(user);
}newuser, old;
int user::check(user abhi)
{f.open("user.txt",ios::in);

 f.seekg(0,ios::beg);
 while(f)
 {
  f.read((char*)this,sizeof(this));
   if(strcmp(id,abhi.id)==0 && strcmp(pass,abhi.pass)==0)
     {cout<<"\n Your id and password found ";
      goto flag;}

  }
  f.close();
  return 0;
  flag:
  return 1;
}

//class for user finished

class question
{char question[250],opt1[25],opt2[25],opt3[25],opt4[25];
int ans,noq;
public:
question()
{strcpy(question,"Enter Question");
 strcpy(opt1,"Enter the Choice");
 strcpy(opt2,"Enter the Choice");
 strcpy(opt3,"Enter the Choice");
 strcpy(opt4,"Enter the Choice");
 ans=0;
noq=0;}
int displayq(int);   //to display the question
int find_qno();      //to find the no of questions in the file
void getq();         //to write the question in the file
void print();        //to display the contents of the file
} q;     //object of the class
int question::displayq(int q_no)
{g.open("question.txt",ios::in);
g.seekg((q_no-1)*sizeof(this),ios::beg);
g.read((char*)this,sizeof(this));
cout<<"Your quesion is :";
puts(question);
cout<<"\n 1.";
puts(opt1);
cout<<"\n 2.";
puts(opt2);
cout<<"\n 3.";
puts(opt3);
cout<<"\n 4.";
puts(opt4);
cout<<"Your answer is (1/2/3/4):";
cin>>p_ans;
if(p_ans==ans)
 return 100;
 else return -50;
}

int question::find_qno()
{g.open("question.txt",ios::in);
 noq=0;
 while(g)
 {g.read((char*)this,sizeof(this));
  noq++;
 }
 g.close();
  return noq;
 }
void question::print()
{g.open("question.txt",ios::in);
 g.seekg(0,ios::beg);
 while(g)
{
 g.read((char*)this,sizeof(this));
 cout<<"Quesion "<<noq<<" is :";
 puts(question);
 cout<<"\n 1.";
 puts(opt1);
 cout<<"\n 2.";
 puts(opt2);
 cout<<"\n 3.";
 puts(opt3);
 cout<<"\n 4.";
 puts(opt4);
}
}

void question::getq()
{cout<<"Enter your question (max 249 characters without pressing enter)";
 gets(question);
 cout<<"\n Enter option 1 (max 24 characters)";
 gets(opt1);
 cout<<"\n Enter option 2 (max 24 characters)";
 gets(opt2);
 cout<<"\n Enter option 3 (max 24 characters)";
 gets(opt3);
 cout<<"\n Enter option 4 (max 24 characters)";
 gets(opt4);
 cout<<"\n Enter the answwer";
 cin>>ans;
 find_qno();
 noq++;
 g.open("question.txt",ios::app|ios::out);
 g.seekg(0,ios::end);
 g.write((char*)this,sizeof(this));
 g.close();
}

void main()
{clrscr();
int ch,ch1,ch2,ch3,x;
char ch4;
menu:
do{cout<<"\n \n \n \t MENU \n \n 1.Administrator \n 2.Player \n \n Enter your choice (1/2):";
  cin>>ch1;
  switch(ch1)
   {case 1 :cout<<"1.Add questions \n \n2.Exit to main menu \n \n 3.Display all the questions \n \n Enter your choice (1/2/3):";
       cin>>ch2;
       switch(ch2)
       {case 1: clrscr();
         add:
         q.getq();
         cout<<"Do you want add some more questions (y/n)";
         char q_choice;
         cin>>q_choice;
         if(q_choice=='y')
         goto add;
         else
         goto menu;

         case 2: clrscr();
         goto menu;

         case 3: clrscr();
         q.print();

        }
        break;
    case 2: menu3:
       clrscr();
       cout<<"1. New player \n \n2. Previous player  \n \n Enter your choice (1 or 2):";
       cin>>ch3;
       switch(ch3)
       {case 1:clrscr();
         cout<<"Welcome to mastermind club(designed and produced by abhishek) \n \n \n Enter new id (max 50 characters) and password (max 10 characters)";
         newuser.fetch();
         newuser.writedata();
         cout<<"Your id and password has been saved . Thanks for registering yourself \n Your current score is"<<score;
         goto menu;


        case 2:clrscr();
         cout<<"Welcome to Mastermind club (designed and produced by abhishek) \n \n \n Enter your id (max 50 characters) and password (max 10 characters)";
         old.fetch();
         int r=old.check(old);
         //game starts
         if(r==1)
         {cout<<"Menu \n \n 1.Play game \n \n 2.Rules \n \n 3.See who is the present mastermind \n \n 4.Exit to main menu";
         cin>>ch3;
         switch(ch3)
         {case 1:game:
         clrscr();
         randomize();
         x=random(q.find_qno())+1;
         score+=q.displayq(x);
         if(score<0)
         {cout<<"Sorry you are out of the game \n \n Exitting from the club. Thanks for visiting the club";
         getch();
         exit(0);
         }
         cout<<"\n Your current score is:"<<score;
         cout<<"\n Do you wish to quit(y/n):";
         cin>>ch4;
         if(ch4=='n')
         goto game;
         else
         {if(score>max)
         {max=score;
         cout<<"Since, you are the highest scorer till now you will get the golden chance of registering your name on the golden hall of fame.So hertiest congrutulations from mastermind club for becoming the new mastermind \n \n Enter your name:";
         master.store();
         master.who_is_the_master();
         }
         cout<<"Progress being saved \n \n Exitting from the club. Thanks for visiting the club";
         getch();
         exit(0);
         }

         case 2:clrscr();
         cout<<"RULES \n \n \n Your inital score will be zero and you will be asked multiple choice questions.Each correct answer will make you win 100 points and every wrong answer will make you elligible for -50 marks .So, be careful.And once your score is less than zero you are out of the game and if you are the highest scorer till now you will get the golden chance of registering your name on the golden hall of fame.So get ready for becoming the new mastermind. \n \n Moreever you can quit your game any time when you think you have scored enough also you can resume your game with your passwor and id ";
         getch();
         goto game;

         case 3:clrscr();
         master.who_is_the_master();
         goto menu;

         case 4:clrscr();
         goto menu;
         }
        break;
        }
        else
        {cout<<"\n Your id and password not matched \n \n Exitting from the club. Thanks for visiting the club";
         getch();
         exit(0);
        }
       }


     }
    }while(ch=='y');
getch();
}


Answer
#include<fstream.h>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

none of these are standard C++ headers.
<conio.h> is not even a standard C header.
<iostream.h>, <fstream.h> are pre-standard headers; they were never part of standard C++. use

#include<fstream>
#include<cstdlib>
#include<cstdio>
#include<cstring>

instead. add a
using namespace std ;
directive if you want.

i have not gone through your compolete code; only looked at the file io part (which is what you seem to be having trouble with).

1. for doing unformatted io with read/write, open the file in binary (and not text) mode so that escape sequence translations will not be performed.

2. rather than

fstream f,g;
class mastermind
{
   // ... elided
   void store()
   {
       gets(name);
       score=max;
       f.open("mastermind.txt",ios::out);
       f.write((char*)this,sizeof(this));
       f.close();
   }
   // ... elided
};

it is cleaner (and easier) to use an ofstream to write (and an ifstream to read)

class mastermind
{
   // ... elided
   void store()
   {
       gets(name);
       score=max;
       std::ofstream f( "mastermind.bin", std::ios_base::binary );
       f.write( (char*)this, sizeof(*this) );
   }
   // ... elided
};
the constructor opens the file, the destructor would close it.

3. the above snippet also corrects another problem in the code.
this is a pointer; mastermind* in the above example.
you are only writing/reading sizeof(pointer) bytes; you should be reading/writing sizeof(mastermind) bytes.
use sizeof(*this) or sizeof(mastermind) instead of sizeof(this).

4. you may want to verify that the stream has been opened successfully. eg.
       std::ofstream f( "mastermind.bin", std::ios_base::binary );
       if( !f )
       {
         // failed to open file
       }  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.