Writing an integer into an ifstream C++ - c++

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

Related

how do i legitimately change filename value of ofstream object?

I'm having troubles with ofstream , which is - when I change value of ofstream object like this
ofstream o_save;
/*code*/
o_save = ofstream(filename); //Problem is here
...the line above completely erase contents of file.
The question is how do I legitimately change filename value of ofstream object ?
P.S. I cant define it when I declare it, because I want it global and I'm not sure which save file I select.
The question is quite vague and contradictory, and the OP seems to have slept after asking the question. So I shall try to peek inside his head and try to elaborate what he wants.
For opening a file, there are many modes for that. Open it like this.
ofstream o_value ;
o_value.open("file.txt") ;
If you want to preserve the original contents of that file, use..
o_value.open("file.txt", ios::app) ;
If you want to close it later and open another one, close using...
o_value.close() ;
Chaning of file names is normally not allowed in case of ofstream. You can use rename from <cstdlib>. You can delete a file though using remove("file.txt") in <cstdio> .
What does it mean to "change the name" of an ofstream object?
The only "name" an ofstream object has is the name of the
variable. An ofstream object is a data stream. You can (on
some systems) change the name of the file it is associated with,
using rename, but somehow, I don't think this is what you want
either. You can also close the stream, and reopen it on another
file.
You cannot assign between iostream objects. If worse comes to
worse, you can declare the global object as a pointer, and
assign to it (using *o_save to write to it).
Finally, the standard says that when you open an ofstream, you
truncate the file, if one exists. If this is not what you want
to do, then you have to add some flags to the open mode. If you
add std::ios_base::app, for example, you will no longer
truncate the file, and all writes will be to the end of file
(atomically, if the system supports it). Alternatively (albeit
quite surprising), you could add std::ios::in to the flags;
this will fail if the file doesn't exist, but will allow writing
anywhere in the file. This is the only way to open a file for
writing if you want to be able to write anywhere in the file,
even if you don't want to read it.
The ofstream does not have some kind of an abstract name attribute, the name is just a parameter to some of its member functions, in that sense asking how to
change filename value of ofstream object
is meaningless.
In general you can rename files with std::rename from <cstdlib> or use Boost.Filesystem.

C++ filestream problem

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).

How to copy files in Visual C++?

I am using Visual C++. How to copy the content of this file to another file?
UINT32 writeToLog(wstring log)
{
wfstream file1 (LOG_FILE_NAME, ios_base::out);
file1 << log;
file1.close();
// want to copy file1 to file2
return 0;
}
What exactly do you want to do? If you need a copy of the data, you can read it in and write it back out again. If you really need a copy of the file, you have to use OS specific calls.
In many cases, reading in the file data and then writing it out again to a different file is a close enough approximation to a copy - like this:
ifstream file1(...);
ofstream file2(...);
std::copy(istream_iterator<char>(file1),istream_iterator<char>(),ostream_iterator<char>(file2));
However that really isn't a copy - it's creating a new file with the same contents. It won't correctly handle hard links or symlinks, it won't correctly handle metadata and it will only 'copy' the default file stream.
If you need a file copy on Windows you should call one of CopyFile, CopyFileEx or CopyFileTransacted depending on your exact requirements.
Standard C++ has no file copying facility, other than reading the file into memory and writing it out again to a different file. As you are using Windows, you can use the CopyFile function - other OSs have similar, OS-specific functions.
The above code from Joe Gauterin did not work for me. I was trying to copy a .tga image file, so maybe something about istream_iterator<char> screwed it up. Instead I used:
ifstream file1(...);
ofstream file2(...);
char ch;
while(file1 && file1.get(ch))
{
file2.put(ch);
}

Reading bmp file for steganography

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.

fstream replace portion of a file

When I do
fstream someFile("something.dat", ios::binary|ios::out);
someFile.seekp(someLocation, ios::beg);
someFile.write(someData, 100);
It seems to replace the entire file with those 100 bytes instead of replacing only the appropriate 100 bytes, as if I had specified ios::trunc. Is there a portable way to not have it truncate the file?
Edit: adding ios::in seems to do the trick, by why is this required, and is that standard behavior?
Edit #2: I am not trying to append to the existing file. I need to replace the 100 bytes while leaving the rest unaffected.
You want the append flag, ios::app, if you want to write at the end of the file.
To do it somewhere arbitrarily in the middle of the file, you need to seek to the right place. You CAN do this by opening the file for in and out, but if I were you I'd create a temp file, copy input up to mark, write your new data, copy the rest to EOF, close the files and replace the previous version with the temp file. This is called a "Master File update".
AFAIR ios::out only specifies the file is for output and ios:binary only specifies the files is binary. The default behaviour for a stream is to create a new file and overwrite the old file. If you want to modify an existing file you must open the file with the ios::app flag.
ATM I cannot check my references so be sure to double check, but I felieve that is accurate.
Since the file already exists open it in 'read+write' mode and then do seekp. I think it will work.
fstream someFile("something.dat", ios::binary|ios::out|ios::in);
someFile.seekp(someLocation, ios::beg);
someFile.write(someData, 100);
The ios:in mask tells the file pointer to position at the beginning of the file so it can start reading in from the start. But, you may want to use fseek to set the file pointer at the beginning of the file.