I'm making a simple game in C++ and I want the highest score at the end of the game to be written in a text file. I'm using fstream to first read the last saved highscore and compare it to the new highscore. The output in the text file looks like this (0НН) and it shouldn't. I'm realy frustrated with this.
Here's a part of my code.
double score_num=0;
fstream datafile("score.pon"); //Declaration of variables
...
if(SPEED>score_num)
{
score_num=SPEED;
}
//getting the score
...
datafile<<score_num; //Writing it to the file
#include <iostream>
#include <fstream>
using namespace std;
#define SPEED 12
int main()
{
double score_num=0;
ofstream datafile("score.pon"); //Declaration of variables
if(SPEED>score_num)
{
score_num=SPEED;
}
//getting the score
datafile<<score_num; //Writing it to the file
return 0;
}
Replaced fstream by ofstream works like a charm. Perhaps you should show more code? Also, closing the file is good habit:
datafile.flush();
datafile.close();
I'll leave errorhandling to you
Hacky solution - open the file as an ifstream, read existing value, close it, adjust score, open file as an ofstream, write score, close it. Alternatively, investigate the use of the seekp() function, and write the score as a binary value, not as text.
My best guess as to why the original was failing is that when you read the last character from a file, the EOF bit is set. In this state, all read & write operations fail. You can write to a file stream that's reached its end by calling clear first.
// the following doesn't truncate file, or handle other error conditions.
if (datafile.eof()) {
datafile.clear();
}
datafile.seekp(0, std::ios_base::beg);
datafile << score_num;
However, this won't solve all your problems. If you write less to the file than its current length (e.g. the old high score was "1.5" and the new high score is "2"), part of the old data will still be present at the end of the file. As long as scores never have a fractional part (in which case you should probably be using an integer type, such as unsigned long), you won't notice the bug, since a < b ⇒ len(a) ≤ len(b). To handle this properly, you'll need to use unapersson's recommended approaches (which will either truncate the file or always write the same amount of data to the file), or use a different I/O library (such as your platform's C library or boost) which provide a way to truncate files (such as the POSIX ftruncate).
Related
I want to create a database in a txt file and access it and edit certain parts of it using seekp(), but when I open the file to write in it , the program creates a new file deleting the previous one.
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream g;
g.open("text.txt",ios::out);
if(!g.is_open())
cout<<"error";
else {
g.seekp(2);
g.write("apple",5);
}
g.close();
return 0;
}
You'll need a different open mode.
The documentation is quite obscure when it comes to the behavior of ofstream (for all practical purposes, the behavior you observe is by design: it will truncate).
Use fstream with ios_base::in | ios_base::out | ios_base::binary instead.
Unless you're using some encoding where one character is always one, two, or four bytes, you won't be able to consistently do this with a text mode. Also, writing at any seek position before end-of-file won't shift content past the current seek position, it is simply overwritten. So in order to achieve a database-like behavior, you're at least going to need some kind of fixed-size records or an indexing data structure.
The program almost runs but i am not sure how to make the .txt file for this , its not giving me an error.
the project asks me to:
" File encryption is the science of writing the contents of a file in a secret code. Your encryption program should work like a filter, reading the contents of one file, modifying
the data into a code, and then writing the coded contents out to a second file.
The second file will be a version of the first file, but written in a secret code. Although there are complex encryption techniques, you should come up with a simple one of your own. For example, you could read the first file one character at a time, and add 10 to the ASCII code of each character before it is written to the second file. "
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char ch;
fstream fin, fout;
fin.open("testone.txt", ios::in);
fout.open("encrypted.txt", ios::out);
while (!fin.eof())
{
fin.get(ch);
fout.put(ch + 10);
}
fin.close();
fout.close();
system("pause");
return 0;
}
Read this -
Error LNK1561: entry point must be defined
https://social.msdn.microsoft.com/Forums/vstudio/en-US/e1200aa9-34c7-487c-a87e-0d0368fb3bff/error-lnk1561-entry-point-must-be-definedproblem-in-c?forum=vclanguage
Not up on my Visual C, but you may need #include <cstdlib> to get system
LNK1561 means your main function can't be found. Clearly the main function is present, so this should compile. Follow Beta's suggestion and ensure you can compile and run a trivial program.
Putting Compiling issues aside, This code won't work.
Overarching Problem: You are not checking for any errors along the way, so there is no way for your program to tell if anything has gone wrong.
For example, what if the file didn't open? The while (!fin.eof()) becomes an infinite loop. If the file is not open, you can never read EOF. Trying to use EOF as a loop condition is a bad idea anyway. Definitely read the link in #Steephen's comment.
If you fail to read a character with fin.get(ch); then what? The current code tries to use the character anyway. Bad idea.
Testing a stream is pretty simple. if (!fin) does the job. Read up on how streams work to learn why. Thius simple test doesn't tell you what went wrong, but at least you know something went wrong.
To make things easier, most stream functions return the stream. This lets you chain stream operations together and makes if (!fin.get(ch)) an easy way to tell if get worked.
So your IO loop can be as simple as
while (fin.get(ch) && fout.put(ch + 10))
{
}
If get couldn't get ch for any reason--unopened file, end of file, unreadable file--the while loop exits. Afterwards you can query fin to find out why. If EOF, awesome. If not EOF, the output file's probably wrong.
The same applies to put. If put failed, the loop ends. Test for why and decide if you want to keep the file.
I also recommend dropping a quick test at the end of main to print out a check.
fin.open("encrypted.txt", ios::in);
while (fin.get(ch) && std::cout.put(ch - 10))
{
}
A better test would be to read the character, undo the encryption, and compare against the original input.
I'm working on an assignment for my computer science class, its a first year course as I'm a beginner and I am having trouble with a certain part.
A quick explanation of what my assignment does is:
It takes information from a text file and puts it in a vector while the program is running, and you can add names to it or remove names from it, and once you are done you need it to save the information, which means you have to take the information back out of the vector and replace it into the text file.
I haven't learned of a way to take information out of a vector and back into a text-file, I saw that a classmate of mine posted on here a few times but he was pretty much dismissed so he told me to ask the question for myself.
We were given a bit of the coding for our program and honestly I have got no clue on how to make the function take the information back out of the vector and into the text file updated.
What ive included:
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
here is the function in which it would save into, any help would be greatly appreciated.
void quit_program(string strFileName, vector<string>&vecThisStudent)
{
//write the body of the function
//Hint: this is the function you should write the vector’s content back to the file.
cout<<"Thanks for using the program. Program terminated"<<endl;
}
As you can see we were even given the hint on what the function was supposed to do, but anyone I have spoken to from the class hasnt had a clue on how to get it done (or they dont like me enough to tell me)
If the entire program is needed, I can post it. It looks almost identical to my classmate who posted earlier, but that is just because we were given the majority of the code and we just had to complete a few different things, and I've just been stuck here for the last 10 hours or so.
My read_file
int read_file(string strFileName, vector<string>&vecThisStudent, fstream &inFile)
{
string strFirstName
string strLastName;
inFile.open(strFileName.c_str(), ios::in | ios::out | ios::app);
while (inFile >> strFirstName >> strLastName)
{
vecThisStudent.push_back(strFirstName + " " + strLastName);
}
return 0;
}
Split the problem into sub-problems. Keep splitting to a smaller pieces till each piece is manageable.
In your case sub-problems I would be comfortable working with are "C++ performing action at program exit", "C++ container serialize", "C++ file IO".
The first one will give you C: Doing something when the program exits, the second - ostream iterator usage in c++, and finally the third one - Writing in file C++.
As a final step you just need to combine all three back together.
And Steve, do not blame your professor or your destiny. Being a good programmer is as hard as being a good surgeon, as hard and as rewarding, but requires quite a bit of dedication to grow from mediocrity to a sharp Swiss Army Knife. At your first job interview you'll see how much worse questions can be than ones asked in these assignments.
Seeing your lack of C++ knowledge, I would REALLY suggest watching some tutorials about C++. If you don't know what a for-loop is/how to use it, you will have MAJOR problems with future assignments.
Here are some great series of tutorial.
There's no such thing are taking the contents of a file (or vector) and placing it automatically into a vector (or file).
But to read or write data, take a look at this page.
The general idea of reading a file is:
Iterate though the file and read each input one by one.
Place that input into a vector
The general idea of outputting data to a file is:
Iterate though the data (ex: every element of that vector)
Output that data (ex: that element).
By iterating, I mean running though the data (usually by a for-loop):
int write_file(string strFileName, vector<string>&vecThisStudent, fstream &outFile)
{
outFile.open(strFileName.c_str(), ios::in | ios::out | ios::app);
for (int i = 0 ; i < vecThisStudent.size() ; i++) {
//Use this line to output to console
cout << vecThisStudent[i] << " \n";
//Use this line to output to file
outFile << vecThisStudent[i] << "\n";
}
}
Use ofstream
http://www.cplusplus.com/reference/fstream/ofstream/
Open File..
Write data using << (http://www.cplusplus.com/reference/ostream/ostream/operator%3C%3C/)
Close file..
I am not sure what exactly you stuck with..
Okay, so, I can now read from .txt files as variables, but how do I write the integers once changed back into my text file?
Example:
xps.open ("xp.txt"); //Text file is loaded and applied to ifstream 'xps'
int xp;
xps >> xp; //xps is applied to integer xp
xp += 50; //xp has 50 added to it's value
and then I want the value of xp to be written (overwriting the previous number) into xp.txt, so how would I do this?
It's inefficient to write and overwrite the same value. Just wait until you know what value you want to write to the file, and write it.
I presume you mean ofstream rather than ifstream since you are writing to the file in this question. If you absolutely have to go back in the file then you need to call seekp(). In order to do this you need to remember the point in the file to start writing to which you can get by calling tellp(). So, if you want my advice, try not to have to re-write the value.
You need to open the text file for both reading and writing; declare xps as an fstream and then you can just do
xps << xp
I am trying to read a bmp file in C++(Turbo). But i m not able to print binary stream.
I want to encode txt file into it and decrypt it.
How can i do this. I read that bmp file header is of 54 byte. But how and where should i append txt file in bmp file. ?
I know only Turbo C++, so it would be helpfull for me if u provide solution or suggestion related to topic for the same.
int main()
{
ifstream fr; //reads
ofstream fw; // wrrites to file
char c;
int random;
clrscr();
char file[2][100]={"s.bmp","s.txt"};
fr.open(file[0],ios::binary);//file name, mode of open, here input mode i.e. read only
if(!fr)
cout<<"File can not be opened.";
fw.open(file[1],ios::app);//file will be appended
if(!fw)
cout<<"File can not be opened";
while(!fr)
cout<<fr.get(); // error should be here. but not able to find out what error is it
fr.close();
fw.close();
getch();
}
This code is running fine when i pass txt file in binary mode
EDIT :
while(!fr)
cout<<fr.get();
I am not able to see binary data in console
this was working fine for text when i was passing character parameter in fr.get(c)
I think you question is allready answered:
Print an int in binary representation using C
convert your char to an int and you are done (at least for the output part)
With steganography, what little I know about it, you're not "appending" text. You're making subtle changes to the pixels (shading, etc..) to hide something that's not visually obvious, but should be able to be reverse-decrypted by examining the pixels. Should not have anything to do with the header.
So anyway, the point of my otherwise non-helpful answer is to encourage you go to and learn about the topic which you seek answers, so that you can design your solution, and THEN come and ask for specifics about implementation.
You need to modify the bit pattern, not append any text to the file.
One simple example :
Read the Bitmap Content (after header), and sacrifice a bit from each of the byte to hold your content
If on Windows, recode to use CreateFile and see what the real error is. If on Linux, ditto for open(2). Once you have debugged the problem you can probably shift back to iostreams.