c++ how modify file using fstream - c++

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.

Related

There is a way to open a binary file with c++, with ofstream, without it being opened in ios::trunc mode?

I write someThing to the file, and that's fine, then when I write otherThing from the 4th byte on the same file, the file should say "someotherthing" but there are 4 empty bytes and then "otherthing". The file appears to have been opened in trunc mode. Is there a way to edit the binary file without reading the whole file and put it in a string, make the changes on the string and then write the string to the file?
string fileName = "fileName.bin", someThing = "something", otherThing = "otherthing";
fstream file;
file.open(fileName, ios::out | ios::binary);
file.write(someThing.c_str(), sizeof(someThing);
file.close();
file.open(fileName, ios::out | ios::binary);
file.seekp((streampos)(4));
file.write(otherThing.c_str(), sizeof(otherThing);
file.close();

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)

Can't append text to specific position in C++

I'm trying to add text to a specific position in C++ with ofstream and seekp. However, it always append to the end of the file.
I've alredy tried to write with file.write(string, len), but the result is so the same.
My code:
void printHistory(int media, time_t timestamp){
ofstream file("history.json", ios::app);
long initial_pos = file.tellp();
file.seekp(initial_pos-3);
file << ", [" << timestamp << "," << media << "]]\n}";
file.close();
}
How about something like:
fstream fs ("fred.txt", ios::in | ios::out);
fs.seekg (0, ios::end);
streamoff filesize = fs.tellg();
fs.seekp (filesize - 3); // locate yourself 3rd char from end.
fs.write( "X", 1 );
fs.close();
Generally, to "insert" you have to write to a temporary stream or file. You cannot actively update in the middle.
Lots of STL types support insertion, but it is simulated via behind the scenes processes.
pseudo code:
pos = some_int_point_in_file
open(file) as f and open(tmp) as t:
read f into t until pos then
insert whatever
finishing reading the rest of f into t
swap file and tmp

Strings retrieved from files displaying garbage

I have 2 files, easyp.txt and easyn.txt, were easyp.txt stores points, and easyn.txt stores names. I have code that displays the top score and the players name. It was working fine, then I edited some other lines, and upon running again, it spews out rubbish. The codes look like this:
case 1:
infile.open("easyn.txt", ios::out | ios::app);
ofile.open("easyp.txt", ios::out | ios::app);
while (getline(infile, STRINGT) && getline(ofile, STRINGO))
{
istringstream buffer(STRINGO);
buffer >> value;
if (infile.eof() && ofile.eof()){
printf("The top player for easy is %s with only %i tries!", STRINGD, value);
break;
}
if (value < best)
{
STRINGD = STRINGT;
best = value;
}
}
infile.close();
ofile.close();
_getch();
break;
(lower number of points is better btw)
When I run the program it outputs random ascii characters as the player name, and 1835884884 as the score.
Yes I am using namespace std
The only other time I have file reading/writing is in the following:
ofstream myfile;
myfile.open("easyn.txt", ios::out | ios::app);
if (myfile.is_open())
{
myfile << chName << "\n";
myfile.close();
}
myfile.open("easyp.txt", ios::out | ios::app);
if (myfile.is_open())
{
myfile << iTurns << "\n";
myfile.close();
}
Thanks for the help
The main problem with your program is this:
printf("The top player for easy is %s with only %i tries!", STRINGD, value);
The %s format specifier to printf expects a char *, not a std::string. What you want to do to fix that is replace STRINGD with STRINGD.c_str().
Passing an argument to a varargs function of another type than the function expects to receive invokes undefined behavior. Exactly what happens depends on your architecture and ABI, so I can't really give a detailed explanation about that without such details, but I don't think that matters much anyway. :)
I don't know if this help's but instead of using the .txt extension, use the .dat extension. Maybe it would help?
.dat files are "data files" that can be opened by text editors, so I though this might help >_>
and I'd try not use ios::out | ios::app, even if you do use them, your doing it wrong. check here if you wanna fix that -> fileStreaming C++ tutorial, mostly because you'd use ios::out | ios::in in most cases.
And you could use other things besides while (getline(infile, STRINGT) && getline(ofile, STRINGO)) personally I'd never use that, mostly because it's just my preference.

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