C++ File Output for object arrays - c++

Does anyone know how to fout an array like the below to a .dat file?
Let me know if this is not enough information.
My console output shows 4 rows of integers with 6 columns and I want to print that to my file. I can print everything else, but can not figure this one out..
for(i=0; i < 4; i++)
{
cout << " " << i+1;
P[i].TeamOutput();
}
void TeamOutput()
{
cout << teamwork << speed << power << defence << injury << endl;
}

You almost had it. You need a specific type of ostream to output. cout is an ostream, but a special one that outputs to the system's console. You need an ostream that outputs to a file. This kind of ostream is called an ofstream and is in the header file <fstream>. Here's how you can use it with an array.
#include <iostream>
#include <fstream>
using namespace std; // It's generally bad to do this
int main()
{
// Size of array
const int SIZE = 10;
// Make the array
int some_array[10];
// Fill the array with values
for (int i = 0; i < SIZE; i++)
{
some_array[i] = i + 1;
}
// THIS is where the magic happens; make the file stream to output to
ofstream file("file.dat"); // "file.dat" can be replaced by whatever filename
// Make sure the file opened okay. Otherwise, there's an error
if (file.is_open())
{ // The file opened just file, so do whatever you need to
// Save all the info from the array to "file.dat"
for (int i = 0; i < SIZE; i++)
{
file << some_array[i] << endl;
}
// Make sure to close the 'ofstream' when you're done
file.close();
}
else
{ // The file did NOT open okay; there's an error
cout << "Error opening file.dat!" << endl;
}
}

Related

Iteratively accessing and writing to multiple files using ofstream

I have a pair of header files. Within IsingModel.h, publically I declare:
ofstream logfile1;
ofstream logfile2;
Then to open the relevant files (logfile1 and logfile 2 have different names) I use:
do {
name2.str(""); //reset name stringstream
n++; //increase n value
name2 << "output_" << gridSize << "_" << seed << "_" << n << "_eqmCalc.txt"; //stream created
} while (if_exist(name2.str())); //test if file already exists
logfile2.open(name2.str());
Which works in creating the file. Then, throughout the code I use the ofstreams to act on the files, for example:
logfile1 << counter << " " << calcM() << " " << calcE() << endl;
This is fine for actions that are independent for each file, however when I call the destructor I want to write the same standard information to each file. To that end, I am experimenting with iteratively writing to the files and it does not seem to work:
void IsingSystem::test() {
for (int i = 1; i = 2; i++) {
if (ofstream("logfile" + to_string(i)).is_open); {
ofstream("logfile" + to_string(i)) << "success" << endl;
}
}
}
This instead creates files called logfile1 and logfile2. As an alternative, I tried to create an array of ofstreams:
void createFileHandles() {
const int count = 2;
std::ofstream logfile[count];
}
But, I could not work out how to pass this between functions properly.
What is the proper way of handling ofstreams so that I can have multiple files open, writing different instructions to them simultaneously but also have some actions that happen to both?
You can have a vector of ofstream
vector<ofstream> ofstreams(2);
//fill vec
for (int i = 0; i < 2; i++)
{
if (ofstreams[i].is_open);
{
ofstreams[i]<< "success" << endl;
}
}
You can then pass ofstreams to functions.

Writing and reading a binary file to fill a vector - C++

I'm working on a project that involves binary files.
So I started researching about binary files but I'm still confused about how to write and fill a vector from that binary file that I wrote before
Here's code: for writing.
void binario(){
ofstream fout("./Binario/Data.AFe", ios::out | ios::binary);
vector<int> enteros;
enteros.push_back(1);
enteros.push_back(2);
enteros.push_back(3);
enteros.push_back(4);
enteros.push_back(5);
//fout.open()
//if (fout.is_open()) {
std::cout << "Entre al if" << '\n';
//while (!fout.eof()) {
std::cout << "Entre al while" << '\n';
std::cout << "Enteros size: "<< enteros.size() << '\n';
int size1 = enteros.size();
for (int i = 0; i < enteros.size(); i++) {
std::cout << "for " << i << '\n';
fout.write((char*)&size1, 4);
fout.write((char*)&enteros[i], size1 * sizeof(enteros));
//cout<< fout.get(entero[i])<<endl;
}
//fout.close();
//}
fout.close();
cout<<"copiado con exito"<<endl;
//}
}
Here's code for reading:
oid leerBinario(){
vector<int> list2;
ifstream is("./Binario/Data.AFe", ios::binary);
int size2;
is.read((char*)&size2, 4);
list2.resize(size2);
is.read((char*)&list2[0], size2 * sizeof(list2));
std::cout << "Size del vector: " << list2.size() <<endl;
for (int i = 0; i < list2.size(); i++) {
std::cout << i << ". " << list2[i] << '\n';
}
std::cout << "Antes de cerrar" << '\n';
is.close();
}
I don't know if I'm writing correctly to the file, this is just a test so I don't mess up my main file, instead of writing numbers I need to save Objects that are stored in a vector and load them everytime the user runs the program.
Nope, you're a bit confused. You're writing the size in every iteration, and then you're doing something completely undefined when you try to write the value. You can actually do this without the loop, when you are using a vector.
fout.write(&size1, sizeof(size1));
fout.write(enteros.data(), size1 * sizeof(int));
And reading in:
is.read(&list2[0], size2 * sizeof(int));
To be more portable you might want to use data types that won't change (for example when you switch from 32-bit compilation to 64-bit). In that case, use stuff from <cctype> -- e.g. int32_t for both the size and value data.

Create loop to write multiple files in C++?

Let's say I have a program that does the follow:
for (i=1; i<10; i++)
{
computeB(i);
}
where the computeB just outputs a list of values
computeB(int i)
{
char[6] out_fname="output";
//lines that compute `var` using say, Monte Carlo
string fname = out_fname + (string)".values";
ofstream fout(fname.c_str());
PrintValue(fout,"Total Values", var);
}
From another file:
template <class T>
void PrintValue(ofstream & fout, string s, T v) {
fout << s;
for(int i=0; i<48-s.size(); i++) {
fout << '.';
}
fout << " " << v << endl;
}
Before implementing that loop, computeB just outputted one file of values. I now want it to create multiple values. So if it originally created a file called "output.values", how can I write a loop so that it creates "output1.values", "output2.values", ..., "output9.values"?
EDIT: I forgot to mention that the original code used the PrintValue function to output the values. I originally tried to save space and exclude this, but I just caused confusion
Disregarding all the syntax errors in your code ...
Use the input value i to compute the output file name.
Use the file name to construct an ofstream.
Use the ofstream to write var to.
Here's what the function will look like:
void combuteB(int i)
{
char filename[100];
sprintf(filename, "output%d.values", i);
ofstream fout(filename);
fout << "total values";
fout << " " << var << endl; // Not sure where you get
// var from. But then, your
// posted code is not
// exactly clean.
}
You can use std::to_string() to convert from an int to a string:
void computeB(int i)
{
if (std::ofstream fout("output" + std::to_string(i) + ".values"))
fout << "total values" << " " << var << '\n';
else
throw std::runtime_error("unable to create output file");
}

C++ How to create a function writing data in file for multiple use with different names

I have some data in an array which is manipulated in about five or six steps. After each step I want the program to write a file with the manipulated data. This is the working code for that:
ofstream mirroreddata("mirroreddata.dat", ios::out);
for (int i = 0; i < n_values; i++)
{
mirroreddata << datavector[i] << "\n";
}
mirroreddata << endl;
mirroreddata.close();
The problem is, that I don't want to write this thing multiple times. I want to create a function I just have to call with the name of the file (here: mirroreddata) and n_values and the datavector. Giving the function the datavector and n_values is no problem, but how to tell her writing the data in a new file? This is the code fragment for this but it is not right:
void CreateDataOutputFile(int n_values, double* datavector)
{
ofstream mirroreddata("mirroreddata.dat", ios::out);
for (int i = 0; i < n_values; i++)
{
mirroreddata << datavector[i] << "\n";
}
mirroreddata << endl;
}
So how to call this but writing data in a new file (for example the smoothed data in file "smoothed")?
Thanks for your answers
Easy: add another parameter for the filename:
#include <string>
void CreateDataOutputFile(int n_values, double* datavector, const std::string& fname)
{
ofstream mirroreddata(fname, ios::out);
for (int i = 0; i < n_values; i++)
{
mirroreddata << datavector[i] << "\n";
}
mirroreddata << endl;
}

What I/O function should I use to write to a .bmp file?

The example code I've seen for this seems to use standard C file output functions, but I'd like to make it in C++.
I tried using fsteam functions to do it, but no data is written to the .bmp file at all.
So far, I have tried the standard <<, put, and write, and none of these work. If I open it up with a hex editor, the file is still empty.
It's odd, since the input functions work fine.
Here's a piece of the code I used to test to see if it was working:
output.open("WHITE.bmp");
output.put('B'); // this doesn't seem to work, the file is empty when I open it in a hex editor.
output.put('M');
And the rest of the code:
#include <iostream>
#include <fstream>
using namespace std;
typedef unsigned char byte;
typedef unsigned short dbyte;
struct BMPINFO
{
int width;
int height;
};
int main()
{
ifstream sourcefile;
ofstream output;
int threshold = 150;
sourcefile.open("RED.bmp");
if(sourcefile.fail())
{
cout << "Could not open RED.bmp" << endl;
return 1;
}
if(sourcefile.get() == 'B')
{
if(sourcefile.get() == 'M')
{
cout << "RED.bmp is a valid .bmp file" << endl;
}
}
else
{
cout << "RED.bmp is not a valid .bmp file" << endl;
return 1;
}
BMPINFO image;
// seeks to bitmap width, this file is little end in.
sourcefile.seekg (0x12, ios::beg);
unsigned int i = (unsigned)sourcefile.get();
i += (unsigned)sourcefile.get() << 8;
image.width = i;
cout << "The width of the image is: " << image.width << endl;
sourcefile.seekg (0x16, ios::beg);
i = sourcefile.get();
i += (unsigned)sourcefile.get() << 8;
image.height = i;
cout << "The height of the image is: " << image.height << endl;
int loc_pixels;
sourcefile.seekg (0x0A, ios::beg);
loc_pixels = sourcefile.get();
cout << "Location of pixel array is: " << loc_pixels << endl;
output.open("WHITE.bmp");
output.put('B'); // this doesn't seem to work, the file is empty when I open it in a hex editor.
output.put('M');
if(output.bad())
{
cout << "the attempt to output didn't work" << endl;
return 1;
}
sourcefile.seekg(loc_pixels, ios::beg);
char data[30000];
output.close();
return 0;
}
Is there a special function I should be using to output to this .bmp file?
EDIT - added more code, though most of it doesn't have to do with file output
You have a buffer overflow bug in this code:
char data[30000]; // Prepare file for usage -- just copy one thing from the file to the other
sourcefile.read(data, image.height * image.width );
You are reading in image.height*image.width bytes, and trying to fit them into 30000 bytes. You should structure your code so that those two numbers are related.
Try this:
std::vector<char> data(image.height * image.width);
sourcefile.read(&data[0], data.size());
There's a great description here.
ofstream myfile;
myfile.open("WHITE.bmp", ios::out | ios::binary); // opening in binary mode
myfile << 'B';
myfile << 'M';
myfile.close();