struct high_scores { char name[10]; int score; high_scores() { strcpy(name,"DEFAULT NAME"); score=-1; } high_scores(const char* _name,const int _score) { strcpy(name,_name); score=_score; } }; bool fexists(const char *filename) { ifstream ifile(filename); //checks if a file exists return ifile; } void AddScore(const char* _scorefile,int score) { if(fexists(_scorefile)) { int flag=0; ofstream outp(_scorefile,ios_base::binary); ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; inp.read((char*)&scores,sizeof(high_scores)*5); for(int i=0;i<5;i++) { if (score>scores[i].score) { if(i!=4) { scores[i+1].score=scores[i].score; } scores[i].score=score; flag=1; } if (flag==1) break; } outp.write((char*)&scores,sizeof(high_scores)*5); inp.close(); outp.close(); //close } else { ofstream outp(_scorefile,ios_base::binary); high_scores scores[5]; scores[0].score=score; outp.write((char*)&scores,sizeof(high_scores)*5); outp.close(); } } void PrintScores(const char* _scorefile) { if(fexists(_scorefile)) { ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; inp.read((char*)&scores,sizeof(high_scores)*5); for(int i=0;i<5;i++) { cout<<i+1<<"o SCORE="<<scores[i].score<<endl; } } else cout<<"FILE DOES NOT EXIST"<<endl; } int main() { AddScore("mpla.txt",100); PrintScores("mpla.txt"); AddScore("mpla.txt",200); return 0; }
Binary File read() problem
Page 1 of 19 Replies - 1501 Views - Last Post: 05 January 2012 - 08:06 AM
#1
Binary File read() problem
Posted 04 January 2012 - 10:36 AM
Hi happy new year to everyone.I am making this game that needs to hold a binary file with highscores.Problem is in line 42 read() doesnt work while in line 94 there is no problem at all.I would really appreciate some help.Thanks...
Replies To: Binary File read() problem
#2
Re: Binary File read() problem
Posted 04 January 2012 - 10:46 AM
Are you sure there is actually something in the file to be read, when you are trying to read it?
This post has been edited by WabiSabi: 04 January 2012 - 10:46 AM
#3
Re: Binary File read() problem
Posted 04 January 2012 - 11:37 AM
Do you realize that by default ofstream.open() and the default ofstream constructor truncate a file when opening? You may want to add some more std::ios flags when you open your file for output to insure the file is not erased, std::ios::app will usually do the trick.
You may also want to consider using std::fstream() to open the file for both reading and writing.
Jim
You may also want to consider using std::fstream() to open the file for both reading and writing.
Jim
This post has been edited by jimblumberg: 04 January 2012 - 11:39 AM
#4
Re: Binary File read() problem
Posted 04 January 2012 - 03:16 PM
Ok thanks very much the help.I corrected it but i still have problem.If someone could tell me why this doesnt work.Sorry if im asking for too much i searched for tutorials but i didnt find something helpfull...
struct high_scores { char name[10]; int score; high_scores() { strcpy(name,"DEFAULT NAME"); score=-1; } high_scores(const char* _name,const int _score) { strcpy(name,_name); score=_score; } }; bool fexists(const char *filename) { ifstream ifile(filename); //checks if a file exists return ifile; } void AddScore(const char* _scorefile,int score) { if(fexists(_scorefile)) { int flag=0; ofstream outp(_scorefile,ios_base::binary | ios::app); ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; inp.read((char*)&scores,sizeof(high_scores)*5); for(int i=0;i<5;i++) { if (score>scores[i].score) { if(i!=4) { scores[i+1].score=scores[i].score; } scores[i].score=score; flag=1; } if (flag==1) break; } cout<<"TELLP2"<<outp.tellp()<<endl; outp.write((char*)&scores,sizeof(high_scores)*5); inp.close(); outp.close(); //close } else { ofstream outp(_scorefile,ios_base::binary); high_scores scores[5]; scores[0].score=score; cout<<"TELLP1"<<outp.tellp()<<endl; outp.write((char*)&scores,sizeof(high_scores)*5); outp.close(); } } void PrintScores(const char* _scorefile) { if(fexists(_scorefile)) { ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; inp.read((char*)&scores,sizeof(high_scores)*5); for(int i=0;i<5;i++) { cout<<i+1<<"o SCORE="<<scores[i].score<<endl; } } else cout<<"FILE DOES NOT EXIST"<<endl; } int main() { AddScore("newi.txt",100); AddScore("newi.txt",200); ifstream test("newi.txt",ios_base::binary); high_scores scores[5]; test.read((char*)&scores,sizeof(high_scores)*5); cout<<scores[1].score<<endl; return 0; }
#5
Re: Binary File read() problem
Posted 04 January 2012 - 03:38 PM
Please describe the problem. Be specific.
Every time I run this program it adds items to the file, is this what you intend to happen?
Jim
Every time I run this program it adds items to the file, is this what you intend to happen?
Jim
#6
Re: Binary File read() problem
Posted 04 January 2012 - 04:11 PM
OK sorry for not specific and thanks again for the help.I want to have a file in which are stored the scores.I want it to have only 5 scores.What i would expect to happend above was cout<<scores[1].score<<endl;
printing 200.
printing 200.
#7
Re: Binary File read() problem
Posted 04 January 2012 - 04:45 PM
The problem is that you're tacking the new array onto the end of the file (after the old array) but each time you read from the file you only read the first five entries (the oldest ones).
I have two suggestions for you:
(1) you should never have the same file opened for two streams (e.g., inp and outp) at the same time.
(2) it's much easier to use ifstream and ofstream separately for input and output than to try to use fstream for both, and in this case you don't NEED to do both simultaneously.
So therefore I suggest that you modify AddScore so it will open inp to read the file, then close it. Then open outp to write the file, then close it. And in main, when you finish reading the file, close it. In short, whenever you are finished reading or writing a file, close it.
And in this application you have no reason to use ios::app because you don't want to append more entries to the end of the file (as you have been doing). Instead, you want to overwrite it with the revised data.
I have two suggestions for you:
(1) you should never have the same file opened for two streams (e.g., inp and outp) at the same time.
(2) it's much easier to use ifstream and ofstream separately for input and output than to try to use fstream for both, and in this case you don't NEED to do both simultaneously.
So therefore I suggest that you modify AddScore so it will open inp to read the file, then close it. Then open outp to write the file, then close it. And in main, when you finish reading the file, close it. In short, whenever you are finished reading or writing a file, close it.
And in this application you have no reason to use ios::app because you don't want to append more entries to the end of the file (as you have been doing). Instead, you want to overwrite it with the revised data.
#8
Re: Binary File read() problem
Posted 04 January 2012 - 05:42 PM
Thanks very much r.stiltskin
It worked with your suggestions i will check it again tommorow and i will repost it in order for other people searching something similar to find it.Thanks again...

#9
Re: Binary File read() problem
Posted 05 January 2012 - 07:42 AM
Ok i finished with it i hope with no errors.Thanks all for the help
If you think it could be done better please tell me...

struct high_scores { char name[10]; int score; high_scores() { strcpy(name,"DEFAULT"); score=-1; } high_scores(const char* _name,const int _score) { strcpy(name,_name); score=_score; } }; bool fexists(const char *filename) { ifstream ifile(filename); //checks if a file exists return ifile; } void AddScore(const char* _scorefile,const char* player_name,int score) { if(fexists(_scorefile)) { int i; ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; //OPEN FILE AND READ SCORES inp.read((char*)&scores,sizeof(high_scores)*5); inp.close(); for(int z=0;z<5;z++) { if (score>scores[z].score) { high_scores temp[5]=scores; scores[z].score=score; //SORT SCORES strcpy(scores[z].name,player_name); for(i=z;i<4;i++) { scores[i+1]=temp[i]; } break; } } ofstream outp(_scorefile,ios_base::binary ); outp.write((char*)&scores,sizeof(high_scores)*5); //wRITE AND CLOSE FILE outp.close(); } else { ofstream outp(_scorefile,ios_base::binary); high_scores scores[5]; scores[0].score=score; //IF FILE DOESNT EXIST CREATE AND FILL FIRST SCORE strcpy(scores[0].name,player_name); outp.write((char*)&scores,sizeof(high_scores)*5); outp.close(); } } void PrintScores(const char* _scorefile) { if(fexists(_scorefile)) { ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; inp.read((char*)&scores,sizeof(high_scores)*5); //PRINT SCORES for(int i=0;i<5;i++) { if (scores[i].score==-1) continue; cout<<i+1<<"o SCORE:"<<scores[i].score<<" "<<"NAME:"<<scores[i].name<<endl;; } } else cout<<"FILE DOES NOT EXIST"<<endl; } int main() { srand(time(0)); AddScore("newi.txt","NICK",rand() %1000); AddScore("newi.txt","GEORGE",rand() %1000); AddScore("newi.txt","JASON",rand() %1000); AddScore("newi.txt","MARY",rand() %1000); AddScore("newi.txt","JACOB",rand() %1000); AddScore("newi.txt","MARIOS",rand() %1000); AddScore("newi.txt","ALEX",rand() %1000); AddScore("newi.txt","MARY",35); AddScore("newi.txt","JACOB",68); AddScore("newi.txt","MARIOS",100); AddScore("newi.txt","ALEX",220); PrintScores("newi.txt"); return 0; }
#10
Re: Binary File read() problem
Posted 05 January 2012 - 08:06 AM
In future don't forget to post the #includes with the rest of the program, without the includes this is not a complete program.
You may consider using fewer blank lines, but add a little more whitespace in your formulas. In my opinion this will make your code easier to read.
Also in C++ code you should try not to use the old C style casts, instead use the C++ style casts. Using the C++ style casts, in my opinion, highlights the cast, and shows that you really mean to cast this variable to a different type.
Jim
You may consider using fewer blank lines, but add a little more whitespace in your formulas. In my opinion this will make your code easier to read.
Also in C++ code you should try not to use the old C style casts, instead use the C++ style casts. Using the C++ style casts, in my opinion, highlights the cast, and shows that you really mean to cast this variable to a different type.
void AddScore(const char* _scorefile,const char* player_name,int score) { if(fexists(_scorefile)) { int i; ifstream inp(_scorefile,ios_base::binary); high_scores scores[5]; //OPEN FILE AND READ SCORES inp.read((char*)&scores, sizeof(high_scores) * 5); inp.read(reinterpret_cast<char*>(&scores), sizeof(high_scores) * 5); inp.close(); for(int z = 0; z < 5; z++) { if (score > scores[z].score) { high_scores temp[5] = scores; scores[z].score = score; //SORT SCORES strcpy(scores[z].name, player_name); for(i = z; i < 4; i++) { scores[i+1] = temp[i]; } break; } } ofstream outp(_scorefile, ios_base::binary ); outp.write(reinterpret_cast<char*>(&scores), sizeof(high_scores) * 5); //outp.write((char*)&scores, sizeof(high_scores) * 5); //wRITE AND CLOSE FILE outp.close(); } else { ofstream outp(_scorefile, ios_base::binary); high_scores scores[5]; scores[0].score = score; //IF FILE DOESNT EXIST CREATE AND FILL FIRST SCORE strcpy(scores[0].name, player_name); //outp.write((char*)&scores, sizeof(high_scores) * 5); outp.write(reinterpret_cast<char*>(&scores), sizeof(high_scores) * 5); outp.close(); } }
Jim
Page 1 of 1