C++ fstream writes garbage to file - c++

The code below creates a vector that contains a vector of chars. It opens a fstream to a file. and then write the first char from the first vector. I tried to methods to write the char. Finally, I tried open a new 'fstream' and from it to print what I wrote. Both the printing and a simple inspection of the file shows it contian nothing, or sometimes garbage (dependening on the order of the writes). No errors or any weried output appear. I'm really loosing my mind over this.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
std::vector<char> y(6, 0);
y[0] = 1;
std::vector<std::vector<char>> vy;
vy.push_back(y);
std::fstream dateir("ffff.dat", std::ios::out | std::ios::out | std::ios::binary);
dateir<<vy[0][0] << endl;
int temp = vy[0][0];
dateir.write((char *)&temp, sizeof(int));
dateir.close();
cout << "here" << endl;
std::ifstream dateir2("ffff.dat", std::ios::out | std::ios::out | std::ios::binary);
if (dateir2.is_open())
{
std::cout << dateir2.rdbuf();
}
else{
cout << "no";
}
dateir2.close();
cout << "end";
return 0;
}

You have...a number of problems here.
std::fstream dateir("ffff.dat", std::ios::out | std::ios::out | std::ios::binary);
Is there a reason you've specified std::ios::out | std::ios::out? It's harmless, but clearly redundant.
As a first stab at things, I'd simplify the code a bit:
std::ofstream out("ffff.dat", std::ios::binary);
int data = 1;
out.write((char *)&data, sizeof(data));
out.close();
std::ifstream in("ffff.dat", std::ios::binary);
int data2;
in.read((char *)&data2, sizeof(data2));
if (data == data2) {
// what we read matched what we wrote
} else {
// what we read didn't match what we wrote
}
When you write binary data to a file, you usually want to just read it back in the way you wrote it out. If you want to look at the individual characters, you can do that but to get something that's semi-readable, you probably want to print them out in hexadecimal, or something on that order (and for this sort of exercise to mean much, you'd probably want to print it out in hex both before writing it out, and after reading it back in, to show they match, and let the reader see a reasonable understandable representation of the file contents).

Related

C++ ofstream Binary Mode - Written file still looks like plain text

I have an assignment that wants plain text data to be read in from a file, and then outputted to a separate binary file. With that being said, I expect to see that the contents of the binary file not to be intelligible for human reading. However, when I open the binary file the contents are still appearing as plain text. I am setting the mode like this _file.open(OUTFILE, std::ios::binary). I can't seem to figure out what I'm missing. I've followed other examples with different methods of implementation, but there's obviously something I'm missing.
For the purpose of posting, I created a slimmed down test case to demonstrate what I'm attempting.
Thanks in advance, help is greatly appreciated!
Input File: test.txt
Hello World
main.cpp
#include <iostream>
#include <fstream>
using namespace std;
#define INFILE "test.txt"
#define OUTFILE "binary-output.dat"
int main(int argc, char* argv[]) {
char* text = nullptr;
int nbytes = 0;
// open text file
fstream input(INFILE, std::ios::in);
if (!input) {
throw "\n***Failed to open file " + string(INFILE) + " ***\n";
}
// copy from file into memory
input.seekg(0, std::ios::end);
nbytes = (int)input.tellg() + 1;
text = new char[nbytes];
input.seekg(ios::beg);
int i = 0;
input >> noskipws;
while (input.good()) {
input >> text[i++];
}
text[nbytes - 1] = '\0';
cout << "\n" << nbytes - 1 << " bytes copied from file " << INFILE << " into memory (null byte added)\n";
if (!text) {
throw "\n***No data stored***\n";
} else {
// open binary file for writing
ofstream _file;
_file.open(OUTFILE, std::ios::binary);
if (!_file.is_open()) {
throw "\n***Failed to open file***\n";
} else {
// write data into the binary file and close the file
for (size_t i = 0U; i <= strlen(text); ++i) {
_file << text[i];
}
_file.close();
}
}
}
As stated here, std::ios::binary isn't actually going to write binary for you. Basically, it's the same as std::ios::out except things like \n aren't converted to line breaks.
You can convert text to binary by using <bitset>, like this:
#include <iostream>
#include <vector>
#include <bitset>
int main() {
std::string str = "String in plain text";
std::vector<std::bitset<8>> binary; // A vector of binaries
for (unsigned long i = 0; i < str.length(); ++i) {
std::bitset<8> bs4(str[i]);
binary.push_back(bs4);
}
return 0;
}
And then write to your file.
In simplest terms, the flag std::ios::binary means:
Do not make any adjustments to my output to aid in readability or conformance to operating system standards. Write exactly what I send.
In your case, you are writing readable text and the file contains exactly what you sent.
You could also write bytes that are unintelligible when viewed as text. In that case, your file would be unintelligible when viewed as text.

c++ - binary files and how can do action on them (print the file)

I write to a file but when I try to read from the file I get an infinite loop
When I work with a regular file I can print this shape but with no binary file. why?
And when I want to do actions on a sample binary file how do I do this if I can not go over the file with a loop?
I would be happy to explain thank you.
main.cpp:
string text;
//getline(cin, text);
text = "3.14159#12#Good Luck!# - 2.718";
char ch2;
fstream outBinary1;// output to text
outBinary1.open("binary1.txt", ios::binary | ios::out);
const char *temp = text.c_str();
outBinary1.write(temp, text.length());
outBinary1.get(ch2);// first char in text
while (!outBinary1.eof()){
cout << ch2 ;
outBinary1.get(ch2);
}
outBinary1.close();
Unfortunately it is hard to understand what you want to establish and have problems with, but I will give it a try.
If you want to read from the file you have to specify ios::inadditionally.
Supposed you want to read from the beginning of the file (after writing), you have to reposition the stream first (according to this). Therefore seekg can be used.
What you want may look like that:
string text;
//getline(cin, text);
text = "3.14159#12#Good Luck!# - 2.718";
char ch2;
// You may want to rename this
fstream outBinary1;// output to text
outBinary1.open("binary1.txt", ios::binary | ios::out | ios::in);
const char *temp = text.c_str();
outBinary1.write(temp, text.length());
outBinary1.seekg(0, outBinary1.beg); // only if you want to read from the beginning
outBinary1.get(ch2);// first char in text
while (!outBinary1.eof()){
cout << ch2 ;
outBinary1.get(ch2);
}
outBinary1.close();
#include <fstream>
#include <iostream>
using namespace std;
void f(){
const string text("3.14159#12#Good Luck!# - 2.718");
fstream outBinary1;
outBinary1.open("binary1.txt", fstream::in | fstream::out | fstream::trunc);
outBinary1.write(text.c_str(), text.length());
outBinary1.seekg (0, outBinary1.beg);
char ch2;
outBinary1.get(ch2);// first char in text
while (outBinary1){
cout << ch2 ;
outBinary1.get(ch2);
}
outBinary1.close();
}
int main(int, char**){
f();
return 0;
}
The two lines to change are
outBinary1.open("binary1.txt", fstream::in | fstream::out | fstream::trunc);
outBinary1.seekg (0, outBinary1.beg);
The first one to force the file to be created and the second one to move the fp back to start. Compiled with g++ and no switches

Writing a string to the end of a file (C++)

I have a program already formed that has a string that I want to stream to the end of an existing text file. All of what little I have is this: (C++)
void main()
{
std::string str = "I am here";
fileOUT << str;
}
I realize there is much to be added to this and I do apologize if it seems I am asking people to code for me, but I am completely lost because I have never done this type of programming before.
I have attempted different methods that I have come across the internet, but this is the closest thing that works and is somewhat familiar.
Open your file using std::ios::app
#include <fstream>
std::ofstream out;
// std::ios::app is the open mode "append" meaning
// new data will be written to the end of the file.
out.open("myfile.txt", std::ios::app);
std::string str = "I am here.";
out << str;
To append contents to the end of files, simply open a file with ofstream (which stands for out file stream) in app mode (which stands for append).
#include <fstream>
using namespace std;
int main() {
ofstream fileOUT("filename.txt", ios::app); // open filename.txt in append mode
fileOUT << "some stuff" << endl; // append "some stuff" to the end of the file
fileOUT.close(); // close the file
return 0;
}
Open your stream as append, new text written to it will be written at the end of the file.
I hope that isn't your whole code because if it is, there's lots of things wrong with it.
The way you would write out to a file looks something like this:
#include <fstream>
#include <string>
// main is never void
int main()
{
std::string message = "Hello world!";
// std::ios::out gives us an output filestream
// and std::ios::app appends to the file.
std::fstream file("myfile.txt", std::ios::out | std::ios::app);
file << message << std::endl;
file.close();
return 0;
}

Write to the middle of an existing binary file c++

I'm trying to open a binary file for writing without erasing the content. But I do not want to write to eof. I want to write to a specific position in file.
Here is a litte example:
ofstream out("test.txt", ios::binary | ios::app);
for(int i = 0; i < 100; i++)
out.put('_');
out.write("Hallo", 5);
out.close();
ofstream out2("test.txt", ios::binary | ios::app);
out2.seekp(10);
out2.write("Welt", 4);
out2.close();
If using app, seek doesn't work. If not using app opening file erases data. Does anybody know an answer?
try the second overload of seekp, which allows you to provide an offset and a direction, this could be begining of file in your case (i.e. ios_base::beg). This of course assumes you know what you are doing and all you want to do is overwrite an existing number of characters.
EDIT: here is fully working example:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
{
ofstream out("test.txt", ios::binary);
for(int i = 0; i < 100; i++)
out.put('_');
out.write("Hallo", 5);
}
{
fstream out2("test.txt", ios::binary | ios::out | ios::in);
out2.seekp(10, ios::beg);
out2.write("Welt", 4);
}
}
When opening with ios::app, it is as if you open a new file that just happened to be attached to an existing file: you can not access the existing file. I'm not sure, because I would do as in Kerrek's answer, but if you really want to try, you probably have to open with "ios::in | ios::out", similar to fopen("test.txt", "rw").
Or as crashmstr points out: ios::out might be enough.
You cannot magically extend the file from the middle. Perhaps easiest to write to a new file: First copy the initial segment, then write your new data, then copy the remaining segment. When all is done, you can overwrite the original file.
According to the specification of fstream here
fstream::open
the ios::app "Sets the stream's position indicator to the end of the stream before EACH output operation." So ios::app doesn't work for replacing, seeks of any sort fail, at least for me.
Just using ios::out does wipe out the file contents preserving only the size, basically turning the file into trash.
ios::in|ios::out turned out as the only working thing for me.
Working Code: This code searches for a string (OLD-STRING) in cout.exe and replaces with a new string (NEW-STRING).
`#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
fstream ifs;
ifs.open ("C:\\Users\\user\\Desktop\\cout.exe", fstream::binary | fstream::in | fstream::out);
std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
size_t pos = str.find("OLD-STRING");
if (pos != string::npos)
{
cout << "string found at position: " << int(pos) << endl;
ifs.seekp(pos);
ifs.write("NEW-STRING", 10);
}
else
{
cout << "could not find string" << endl;
}
if (ifs.is_open())
ifs.close();
return 0;
}`

How to append text to a text file in C++?

How to append text to a text file in C++? And create a new text file if it does not already exist and append text to it if it does exist.
You need to specify the append open mode like
#include <fstream>
int main() {
std::ofstream outfile;
outfile.open("test.txt", std::ios_base::app); // append instead of overwrite
outfile << "Data";
return 0;
}
I use this code. It makes sure that file gets created if it doesn't exist and also adds bit of error checks.
static void appendLineToFile(string filepath, string line)
{
std::ofstream file;
//can't enable exception now because of gcc bug that raises ios_base::failure with useless message
//file.exceptions(file.exceptions() | std::ios::failbit);
file.open(filepath, std::ios::out | std::ios::app);
if (file.fail())
throw std::ios_base::failure(std::strerror(errno));
//make sure write fails with exception if something is wrong
file.exceptions(file.exceptions() | std::ios::failbit | std::ifstream::badbit);
file << line << std::endl;
}
#include <fstream>
#include <iostream>
FILE * pFileTXT;
int counter
int main()
{
pFileTXT = fopen ("aTextFile.txt","a");// use "a" for append, "w" to overwrite, previous content will be deleted
for(counter=0;counter<9;counter++)
fprintf (pFileTXT, "%c", characterarray[counter] );// character array to file
fprintf(pFileTXT,"\n");// newline
for(counter=0;counter<9;counter++)
fprintf (pFileTXT, "%d", digitarray[counter] ); // numerical to file
fprintf(pFileTXT,"A Sentence"); // String to file
fprintf (pFileXML,"%.2x",character); // Printing hex value, 0x31 if character= 1
fclose (pFileTXT); // must close after opening
return 0;
}
You could use an fstream and open it with the std::ios::app flag. Have a look at the code below and it should clear your head.
...
fstream f("filename.ext", f.out | f.app);
f << "any";
f << "text";
f << "written";
f << "wll";
f << "be append";
...
You can find more information about the open modes here and about fstreams here.
You could also do it like this
#include <fstream>
int main(){
std::ofstream ost {outputfile, std::ios_base::app};
ost.open(outputfile);
ost << "something you want to add to your outputfile";
ost.close();
return 0;
}