overwrite a text in a file using c++ - c++

I have a problem with the following code :
fstream s("tst.txt" , fstream::binary);
s.seekp(5, fstream::beg);
s.write("testing", 7);
it should keep the first five character in the file as it is,but it doesn't !
it discard the whole old data,i have to keep the old data and overwrite just a block of file data , and it should be in a binary mode
any one help?
thanks in advance.

Try this:
fstream s("tst.txt" , fstream::binary | fstream::in | fstream::out);
s.seekp(5, std::fstream::beg);
s.write("testing", 7);
By specifying an openmode flag,you are overriding the default openmode in your fstream constructor call.

Related

c++ how modify file using fstream

I want to edit the first 100 characters of a file,
I do this, but the new characters override the previous ones (like the photo)
my code :
fstream fileStreamIn("text.txt", ios::in | ios::out | ios::binary);
int theSize = 100;
string theMainBuffer(theSize, '\0');
fileStreamIn.read(&theMainBuffer.front(), theSize);
theMainBuffer.resize(fileStreamIn.gcount());
//cout << theMainBuffer << endl;
fileStreamIn.close();
fileStreamIn.open("text.txt", ios::in | ios::out | ios::binary);
fileStreamIn << "blahblah ";
fileStreamIn.close();
I want "blahblah" to be added to the contents of the file and the previous contents of "helloworld" not to be deleted
output :
blahblahrld !
è !©ª}2•¼Ü²ù­XkLÉ·ð„!ð–ç„ñWïðʃ¡ åñ·§Dß}ˆ¹mÐÕŠw:—*ËtMÒJf-Öù“hñ<³:rÛä‡ ”‘Ôyv-4mXþeߧzè’¬ŒŽ<¤‘“‰l'g‚Šâ¡;¬Èa|ÔÁ3îú€;‰±Ï.ÖLáÑȽ[ïÿÿúU%ã2§Ls§n~çˆÏÔäÔ™ 4øÒ‘Ö°,y•»Ô'`` ¬ÜgÜò`÷Tº^E1ØàùÛ÷i§d¨Ù`I5»7á8Zéz0¥Ž’3Y7Êœ¦}eíÝΦIm?óbÙOâ-ŸäëŠgýhýR
Â3‘†y±è±/VŠ¤?Ïù4?’ÑûIÆLQ~DãŠ?Ôêð#N ]³böPK ZQamë š PK 5 -
I want this output :
blahblah hello world !
è !©ª}2•¼Ü²ù­XkLÉ·ð„!ð–ç„ñWïðʃ¡ åñ·§Dß}ˆ¹mÐÕŠw:—*ËtMÒJf-Öù“hñ<³:rÛä‡ ”‘Ôyv-4mXþeߧzè’¬ŒŽ<¤‘“‰l'g‚Šâ¡;¬Èa|ÔÁ3îú€;‰±Ï.ÖLáÑȽ[ïÿÿúU%ã2§Ls§n~çˆÏÔäÔ™ 4øÒ‘Ö°,y•»Ô'`` ¬ÜgÜò`÷Tº^E1ØàùÛ÷i§d¨Ù`I5»7á8Zéz0¥Ž’3Y7Êœ¦}eíÝΦIm?óbÙOâ-ŸäëŠgýhýR
Â3‘†y±è±/VŠ¤?Ïù4?’ÑûIÆLQ~DãŠ?Ôêð#N ]³böPK ZQamë š PK 5 -
What is the problem, how can I solve the problem?
thanks
If you don't care to keep the first 100 bytes, simply create 100 lengths of string, change some values and write it to the stream would be enough. Reading a file is not needed.
std::fstream fs("text.txt", ios_base::out | ios_base::binary);
string buffer(100, ' ');
string update="Hello";
buffer.replace(0, update.size(), update);
fs.seekp(20); // move to write position
fs.write(buffer.data(), buffer.size());
fs.close();
Use ios::trunc as the file open mode.
For more info check out this.

How can I open a file in c++, without erasing its contents and not append it?

I am trying to find a way using which I can Edit the contents in a binary file, without reading the whole file.
Suppose this is my file
abdde
And I want to make it
abcde
I tried following:-
Attempt 1)
ofstream f("binfile", ios::binary);
if(f.is_open()){
char d[]={'c'};
f.seekp(2,ios::beg);
f.write(d, 1);
f.close();
}
//the file get erased
Output:
**c
Attempt 2)
ofstream f("binfile", ios::binary | ios::app);
if(f.is_open()){
char d[]={'c'};
f.seekp(2,ios::beg);
f.write(d, 1);
f.close();
}
//the file simple gets append seekp() does nothing
Output:
abddec
Attempt 3)
ofstream f("binfile", ios::binary | ios::app);
if(f.is_open()){
char d[]={'c'};
f.seekp(2);
f.write(d, 1);
f.close();
}
//same as before the file simple gets append seekp() does nothing
Output:
abddec
And if I just try to replace the 1st byte of the file, which is 'a' with 'h'
ofstream f("binfile", ios::binary);
if(f.is_open()){
char d[]={'c'};
f.seekp(ios::beg);
f.write(d, 1);
f.close();
}
//file is erased
Output:
h
What do I do? Is it even possible for the OS to allow a program to edit a file at any point own its own?
std::ios::app means the cursor is put at the end of the file before every write. Seeking has no effect.
Meanwhile, std::ios::binary goes into "truncation" mode by default for an output stream.
You want neither of those.
I suggest std::ios::out | std::ios::in, perhaps by just creating a std::fstream fs(path, std::ios::binary) rather than using an std::ofstream.
Yes, it's a bit confusing.
(Reference)

C++ replace data in binary file with fstream

I try to replace data in binary file using C++ and fstream library. Is it possible to do that with this library?
I would like to change one byte of file in address: 0xB07 to 1.
I have written the following code snippet:
...
int address = 0xB07;
char * toChange = new char('0');
std::ifstream input(filename, std::ios::binary);
input.seekg(address);
input.read(toChange, 1);
input.close();
*toChange = (char)0x01;
std::ofstream output(filename, std::ios::binary);
output.seekp(address);
output.write(toChange, 1);
output.close();
...
I have tried many versions of this code and I still can't understand why the byte doesn't change.
This code will remove your file and put totally new contents in it.
The problem is in line
std::ofstream output(filename, std::ios::binary);
That's because the default open mode is ios::out | ios::trunc (See for ex.: Input/Output with files)
Which means file is being truncated to zero bytes.
Then your seek() function extends him to the specified size (usually filling with zeroes) and finally output.write() writes the byte at the end.
In order to do what you want I had to specify the following ofstream flags: std::ios::binary|std::ios::out|std::ios::in
I cannot say currently for sure why the std::ios::inis needed, sorry...

Write to File's Last 32 Characters

I want to write an info to binary file's last 32 characters. But when i call my writeInfo function, it deletes the whole content. I can read the data before i write, but after i write with this function, it deletes the whole content, instead of writing.
void Info::writeInfo(char *filedestination)
{
ofstream test;
test.open(filedestination, ios::binary);
test.seekp(-32, ios::end); // not sure about seekp
test.write(info, 31);
test.close();
}
Hope you can help, thank you
You have to open the file in read-write mode to prevent the call to open from truncating it:
test.open(filedestination, ios::binary | ios::in | ios::out);
http://www.cplusplus.com/reference/cstdio/fseek/
try using fseek(). link above is documentation

fstream in and out on nonexistent file

Is it possible to open an fstream on a file that does not exist with both ios::in & ios::out without getting an error?
To open an fstream on a file that does not exist for input and output (random access) without getting an error, you should provide the flags fstream::in | fstream::out | fstream::trunc in the open (or constructor) call. Since the file does not already exist, truncating the file at zero bytes is no drama.
You may want an error when opening a file that doesn't exist when specifying only ios::in since you'll never be able to read from the stream so failing early in this case will prevent surprise failures later on.
The answer to your question unfortunately is: "No", this is not possible in a single C++ statement.
Yes, many people will answer, that you can use the combined flags fstream::in | fstream::out | fstream::trunc. But that answer is nonsense. fstream::trunc means, that the output file will be truncated to size zero upon opening. But then, why would you like to open an empty file for reading and writing? Except for the rare case, that you need a file as a temporary store for some of your application's data, that you will first write and later read back, there is no use for this flag combination.
Some people recommend to first try to open with fstream::in | fstream::out (and possible further flags like fstream:app or fstream::binary as needed) and then check the file's error status: If the file could not be opened, then re-try the open operation including | fstream::trunc. This solution has several caveats, however. For example, if your file system is mounted via NFS, the first attempt to open the file in read/write-mode might fail due to temporary network issues. If the second attempt (the one including the fstream::trunc flag) then succeeds, there goes your wounderful data, that you have collected so far.
The safe solution is to first open the file for appending only (which will create the file, if it doesn't exist, but will not truncate it) and then close it immediately and open it a second time in read-write mode. This can be achieved with the following code: Note, that an ofstream is first constructed and then immediately discarded.
std::string filename { "test.txt" };
(void) std::ofstream(filename, std::ostream::app);
std::fstream file(filename);
Alternatively, if you need further flags, like binary, use:
std::string filename { "test.txt" };
(void) std::ofstream(filename, std::ofstream::app | std::fstream::binary);
std::fstream file(filename, std::fstream::in | std::fstream::out | std::fstream::binary);
I hope, that in C++25 (or whichever standard is next), they finally add a flag std::fstream::create to create non-existant output files, if read-write-mode is requested.
#include <fstream>
ofstream out("test", ios::out);
if(!out)
{
cout << "Error opening file.\n";
return 1;
}
ifstream in("test", ios::in);
if(!in)
{
cout << "Error opening file.\n";
return 1;
}
If an error occurs the message is displayed and one (1) is returned. However it is possible to compile and execute just ofstream out("test", ios::out); and ifstream in("test", ios::in); without any errors. Either way the file test is created.
#include <iostream>
#include <fstream>
using namespace std;
int main () {
fstream f("test.txt", fstream::in | fstream::out);
cout << f.fail() << endl;
f << "hello" << endl;
f.close();
return 0;
}
This code will print 1 and will not create "test.txt" file, if it does not exit. So it is not possible to open and fstream on a file that does not exist without getting an error.
std::fstream f("test.txt", std::ios_base::out);
f.close(); //file now exists always
f.open("test.txt", fstream::in | std::ios_base::out);
//f is open for read and write without error
I haven't checked to guarantee that it will open without error, but I feel pretty confident that it should.