formatted output: columns - c++

I am desperately trying to produce formatted output by using fstream: columns.
There are two functions (whatever functions Func1, Func2) which produce output (write to the same file, "example.dat"):
#include <fstream>
int main()
{
std::ofstream fout;
fout.open("example.dat");
for (int i=0; i<10; i++)
{
fout << Func1(i) << std::endl;
};
// Func2 depends on Func1, thus them **cannot** be written at the same time:
// fout << Func1() << " " << Func2() << std::endl;
for (int i=0; i<10; i++)
{
fout << Func2(i) << std::endl;
};
return 0;
}
The output will similar to:
Func1(0)
Func1(1)
.
.
.
Func1(9)
Func2(0)
Func2(1)
.
.
.
Func2(9)
My question is: How to produce this output as two columns:
Func1(0) Func2(0)
Func1(1) Func2(1)
.
.
.
While them are not simultaneously written.
I suspect that I need to use seekp(), tellp(), but unfortunately I am not a big expert in this.
Please help!
Thank you in advance.

vector<ostringstream> streams(10);
for (int i=0; i < 10; ++i)
{
streams[i] << Func1(i);
}
for (int i=0; i < 10; ++i)
{
streams[i] << " " << Func2(i);
}
ofstream fout("example.dat");
for (int i=0; i < 10; ++i)
{
fout << streams[i].str() << endl;
}

Why would you need seekp and tellp (and writing to the middle of a file is full of pitfalls for the unwary in any case)
Use a std::vector (syntax is probably wrong), thus:
std::vector<std::string> res1;
std::vector<std::string> res2;
res1.reserve(10);
res2.reserve(10);
for (std::size_t i = 0; i < 10; ++i)
{
std::stringstream s;
s << func1(i);
res1[i] = s.str();
}
//same for res2, func2
for (std::size_t i = 0; i < 10; ++i)
{
cout << res1[i] << " " << res2[i] << "\n";
}
That's probably the wrong formatting and bits will need tuning. And std::list might work better.

Assuming you really cannot keep them in memory, you could write to two files, seek back to the start, read them back in line by line and output to your final file to create your concatenated columns.
Something like this might work (I've not tested it):
#include <fstream>
#include <string>
int main()
{
std::fstream fs_func1;
std::fstream fs_func2;
std::ofstream fout;
fs_func1.open("func1.dat")
for (int i=0;i<10;i++)
{
fs_func1 << Func1(i) << std::endl;
}
fs_func1.seekg(0); // Set get pointer to start of file
fs_func2.open("func2.dat");
for (int i=0;i<10;i++)
{
fs_func2 << Func2(i) << std::endl;
};
fs_func2.seekg(0); // Set get pointer to start of file
fout.open("example.dat");
while (!fs_func1.eof() && !fs_func2.eof())
{
std::string func1_line;
std::string func2_line;
std::getline(fs_func1, func1_line);
std::getline(fs_func2, func2_line);
fout << func1_line << " " << func2_line << std::endl;
}
return 0;
}
There is probably a Unix command line tool that would do this for you in one step.

Untested, but the idea is to treat your file as a grid.
const int COLUMN_COUNT = 2;
const int COLUMN_WIDTH = 8;
const int ROW_WIDTH = COLUMN_COUNT * COLUMN_WIDTH + 1; // + 1 is for endl
void write_cell(std::ostream& out, int row, int column, double value) {
// how many rows is there in the file ?
out.seekp(0, std::ios_base::end);
int row_count = out.tellp() / ROW_WIDTH;
// Do we need to create more rows ?
for(int i = row_count; i <= row; i++) {
out.seekp(ROW_WIDTH - 1, std::ios_base::cur);
out << endl;
}
// compute cell position
int pos = row * ROW_WIDTH + column * COLUMN_WIDTH;
// move to cell position
out.seekp(pos);
// write the cell content
out << std::setw(COLUMN_WIDTH) << value;
}
int main()
{
std::ofstream fout;
fout.open("example.dat");
for (int i=0; i<10; i++)
{
write_cell(fout, i, 0, Func1(i));
};
for (int i=0; i<10; i++)
{
write_cell(fout, i, 1, Func2(i));
};
return 0;
}

for (int i=0;i<10;i++)
{
fout << Func1(i);
};
fout<<endl;
for (int i=0;i<10;i++)
{
fout << Func2(i);
};
fout<<endl;

Related

How do I convert long doubles to char arrays?

I am running a C++ program to sort strings as numbers.
I am saving strings in a char array vector but want to sort numbers as numbers so I am converting number strings into long doubles by calling "tonum()" then converting them back to strings when I am done by calling "tostring()". I am calling "numstr()" strictly for readability and debugging. I convert numbers 0 through 7 and the 6th number across for each value changes every time I run it. In my actual program, the first 5 numbers also seem to change. How do I get consistent results for a long double so that I can properly sort long doubles in char arrays?
#include<iostream>
std::string::size_type sz;
//___________________________________________________
std::string tonum(std::string str)
{
const int len = sizeof(long double);
std::string out = "0000000000000000";
union
{
long double dbl;
char array[len];
};
try
{
dbl = stold(str);
}
catch(std::exception &err)
{
dbl = 0;
}
for (int i = 0; i < len; i++)
{
std::cout << (int)array[i] << "\n";
out[len-i-1] = array[i];
}
return(out);
}
//___________________________________________________
std::string fromnum(std::string str)
{
const int len = sizeof(long double);
std::string out = "";
union
{
long double dbl;
char array[len];
};
for (int i = 0; i < len; i++)
{
array[len-i-1] = str[i];
}
out = std::to_string(dbl);
return(out);
}
//_____________________________________________________
std::string numstr(std::string str)
{
std::string out = fromnum(str) + ":";
for (int i = 0; i < str.length(); i++)
{
std::string look = std::to_string(str[i]);
int lookint = stold(look,&sz);
if (lookint < 0) lookint += 256;
std::string look2 = std::to_string(lookint);
out += look2 + " ";
}
return(out);
}
//_____________________________________________________
int main()
{
std::cout << numstr(tonum("0")) << "\n";
std::cout << numstr(tonum("1")) << "\n";
std::cout << numstr(tonum("2")) << "\n";
std::cout << numstr(tonum("3")) << "\n";
std::cout << numstr(tonum("4")) << "\n";
std::cout << numstr(tonum("5")) << "\n";
std::cout << numstr(tonum("6")) << "\n";
std::cout << numstr(tonum("7")) << "\n";
}
//_____________________________________________________

How would I save the output of this forloop

This is the code I've already written but I would like to be able to save my for loop output to a file. I have tried using different ways like using ofstream around the loop outside the loop and inside the loop. However even though using these my code runs it does not output information to the file like I would like.
#include <iostream>
#include <fstream>
using namespace std;
struct MyStruct {
int number;
int numbertwo;
};
void printStruct(MyStruct thestruct);
int main(){
MyStruct alex[4] = {{15, 20},{30, 35},{45, 50},{60, 65}};
cout<<"Number"<<"\t"<<"Numbertwo"<<endl;
int sizeofarray = 4;
for(int x = 0; x < sizeofarray; x = x+1){
printStruct(alex[x]);
}
}
void printStruct(MyStruct thestruct){
for(int x = 0;x < 1; x++)
if(thestruct.number > 30){
cout<<thestruct.number*10<<"\t"<<thestruct.numbertwo<<endl;}
else if(thestruct.number <= 30){
cout<<thestruct.number*10<<"\t"<<thestruct.numbertwo<<endl;
}
If you add a stream parameter to your printing function you can choose where it goes.
void printStruct(ostream& os, const MyStruct& thestruct);
int main(){
MyStruct alex[4] = {{15, 20},{30, 35},{45, 50},{60, 65}};
int sizeofarray = 4;
// Print to a file
ofstream output("results.txt");
output << "Number" << "\t" << "Numbertwo" << endl;
for(int x = 0; x < sizeofarray; x = x+1){
printStruct(output, alex[x]);
}
// Print the same to stdout
cout << "Number" << "\t" << "Numbertwo" << endl;
for(int x = 0; x < sizeofarray; x = x+1){
printStruct(cout, alex[x]);
}
}
void printStruct(ostream& os, const MyStruct& thestruct){
if(thestruct.number > 30){
os << thestruct.number*10 << "\t" << thestruct.numbertwo << endl;
else
os << thestruct.number*10 << "\t" << thestruct.numbertwo << endl;
}

Why don't people initialize i globally?

So, it seems like 'i' is pretty much the universal counter in C++. It seems like in every for loop, people re-initialize 'i'. I have to ask, why don't they just initialize 'i' globally? 'i' would still have to be re-defined in each loop, so I don't see why there would be any confusion.
It just seems like this:
#include <iostream>
int i=0;
int main()
{
for (i=0;i<3;i++)
{
std::cout << i << "\n";
}
for (i=0;i<5;i++)
{
std::cout << "hello" << "\n";
}
return 0;
}
is easier to read, and faster to write than:
#include <iostream>
int main()
{
for (int i=0;i<3;i++)
{
std::cout << i << "\n";
}
for (int i=0;i<5;i++)
{
std::cout << "hello" << "\n";
}
return 0;
}
Excellent idea!
Here's a program that prints "hellohello" five times:
int i;
void print_twice(const std::string& s)
{
for (i = 0; i < 2; i++)
{
std::cout << s;
}
std::cout << std::endl;
}
int main()
{
for (i = 0; i < 5; i++)
{
print_twice("hello");
}
}
Or... does it? (Ominous organ music plays. The crows caw. Sirens in the distance.)

Looping through array inside of stuct

I'm a student, learning pointers for the first time. My assignment doesn't allow the use of string classes and should be using pointer notation to access all elements within an array (no []).
Why am I not able to access an array inside of a struct via pointers? Is my syntax off?
#include <iostream>
using namespace std;
struct person
{
int favNums[4];
};
// Notation works here
void strCopy(char *from, char *to, int len)
{
for (int i = 0; i < len; i++)
{
*(to + i) = *(from + i);
}
}
// But doesn't work here
void sayNumsPointerNotation(person peep)
{
for (int i = 0; i < 4; i++)
{
//cout << peep.*(favNums + i) << endl;
}
}
// Would like to accomplish this.
void sayNums(person peep)
{
for (int i = 0; i < 4; i++)
{
cout << peep.favNums[i] << endl;
}
}
int main()
{
// Array outside of struct
char from[5] = "Word";
char to[5];
strCopy(from, to, 5);
cout << to << endl << endl;
// Array inside of struct non-pointer
person peep;
peep.favNums[0] = 0;
peep.favNums[1] = 1;
peep.favNums[2] = 2;
peep.favNums[3] = 3;
sayNums(peep);
cout << endl;
sayNumsPointerNotation(peep);
cout << endl;
}
This should work, hopefully you understand what was wrong.
#include <iostream>
using namespace std;
struct person
{
int favNums[4];
};
// Notation works here
void strCopy(char *from, char *to, int len)
{
for (int i = 0; i < len; i++)
{
*(to + i) = *(from + i);
}
}
// But doesn't work here (now it works)
void sayNumsPointerNotation(person* peep)
{
for (int i = 0; i < 4; i++)
{
cout << *(peep->favNums + i) << endl;
}
}
// Would like to accomplish this.
void sayNums(person peep)
{
for (int i = 0; i < 4; i++)
{
cout << peep.favNums[i] << endl;
}
}
int main()
{
// Array outside of struct
char from[5] = "Word";
char to[5];
strCopy(from, to, 5);
cout << to << endl << endl;
// Array inside of struct non-pointer
person peep;
peep.favNums[0] = 0;
peep.favNums[1] = 1;
peep.favNums[2] = 2;
peep.favNums[3] = 3;
sayNums(peep);
cout << endl;
sayNumsPointerNotation(&peep);
cout << endl;
}
Instead of
cout << peep.*(favNums + i) << endl;
Try this:
cout << *(peep.favNums + i) << endl;
Use
cout << *(peep.favNums + i) << endl;
.*, on the other hand, is a "member pointer", and means something different.

How do you convert an int into a string in c++

I want to convert an int to a string so can cout it. This code is not working as expected:
for (int i = 1; i<1000000, i++;)
{
cout << "testing: " + i;
}
You should do this in the following way -
for (int i = 1; i<1000000, i++;)
{
cout << "testing: "<<i<<endl;
}
The << operator will take care of printing the values appropriately.
If you still want to know how to convert an integer to string, then the following is the way to do it using the stringstream -
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
int number = 123;
stringstream ss;
ss << number;
cout << ss.str() << endl;
return 0;
}
Use std::stringstream as:
for (int i = 1; i<1000000, i++;)
{
std::stringstream ss("testing: ");
ss << i;
std::string s = ss.str();
//do whatever you want to do with s
std::cout << s << std::endl; //prints it to output stream
}
But if you just want to print it to output stream, then you don't even need that. You can simply do this:
for (int i = 1; i<1000000, i++;)
{
std::cout << "testing : " << i;
}
Do this instead:
for (int i = 1; i<1000000, i++;)
{
std::cout << "testing: " << i << std::endl;
}
The implementation of << operator will do the necessary conversion before printing it out. Use "endl", so each statement will print a separate line.