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;
}
Related
I want to display a progress bar however putting the printing code inside a separate function seems to invoke an std::flush as each time the progress bar is printing in a new line. This did not happen when the code was used inline
The code:
#include <iostream>
#include <unistd.h>
void load(int curr, int total) {
std::cout << "\n[";
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << "=";
else if (i == pos) std::cout << ">";
else std::cout << " ";
}
std::cout << "]" << int(float(curr)/(float)total * 100.0) << " %\r";
std::cout.flush();
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i,5);
}
std::cout << std::endl;
return 0;
}
What it does:
[> ]0 %
[==========> ]20 %
[====================> ]40 %
[==============================> ]60 %
[========================================> ]80 %
[==================================================]100 %
What it's supposed to do: print all on the same line
The first line in your function outputs \n, which is what makes it print on a new line every iteration.
Fix:
#include <iostream>
void load(int curr, int total) {
std::cout << '[';
int pos = 50 * curr/total;
for (int i = 0; i < 50; ++i) {
if (i < pos) std::cout << '=';
else if (i == pos) std::cout << '>';
else std::cout << ' ';
}
std::cout << ']' << int(float(curr)/(float)total * 100.0) << " %\r" << std::flush;
}
int main(){
for( int i = 0; i <= 5; i++ ){
load(i, 5);
}
std::cout << '\n';
}
I am new to C++ and learning data structures. In the below code I am getting an "out of range warning", and do not understand what I am doing wrong.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> numbers{100,-1,2,4,55,78,3};
int temp {};
int pass {};
pass = numbers.size();
for(int i {0} ;i<pass-1;i++){
for(int j {0} ; j<pass-1-i ; j++){
if(numbers.at(j) > numbers.at(j+1)){
temp = numbers.at(j);
numbers.at(j)=numbers.at(j+1);
numbers.at(j+1)=temp;
}
}
}
cout << numbers.at(0) << endl;
cout << numbers.at(1) << endl;
cout << numbers.at(2) << endl;
cout << numbers.at(3) << endl;
cout << numbers.at(4) << endl;
cout << numbers.at(5) << endl;
cout << numbers.at(6) << endl;
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
return 0;
}
It seems like you may not understand how std::vectors work.
You have only declared 7 elements in your vector which means you can only go up to the index 6. This is because std::vector's indices start at 0. This is true for std::array as well.
vector<int> numbers{100,-1,2,4,55,78,3};
However, in your code you have put these two statements:
cout << numbers.at(7) << endl;
cout << numbers.at(8) << endl;
which doesn't work because like I mentioned you can only go up to index 6.
You should also consider using a for loop like the comments mention above. It is more simple to use and is less work.
For example eith a for loop:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers{ 100,-1,2,4,55,78,3 };
int temp{};
int pass{};
pass = numbers.size();
for (int i{ 0 }; i < pass - 1; i++) {
for (int j{ 0 }; j < pass - 1 - i; j++) {
if (numbers.at(j) > numbers.at(j + 1)) {
temp = numbers.at(j);
numbers.at(j) = numbers.at(j + 1);
numbers.at(j + 1) = temp;
}
}
}
std::cout << "v = { ";
for (int i = 0; i < numbers.size(); i++) {
std::cout << numbers.at(i) << ", ";
}
std::cout << "}; \n";
return 0;
}
Output:
v = { -1, 2, 3, 4, 55, 78, 100, };
I have a problem in using auto declarations. I write a program in Visual Studio 2017 as follow:
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
class MyClass
{
public:
struct mystruct {
vector<int> vi;
};
vector<mystruct> TheStructV;
void AddStructV() {
TheStructV.push_back(mystruct());
};
};
int main()
{
MyClass MyObj[3];
for (int a = 0; a < 3; a++) {
MyObj[a].AddStructV();
for (int i = 1; i <= 5; i++) {
MyObj[a].TheStructV[MyObj[a].TheStructV.size() - 1].vi.push_back(i * 10 + idx);
}
idx++;
}
for (int b = 0; b<3; b++) {
cout << "MyObj[" << b << "] struct vector size:" << MyObj[b].TheStructV.size() << endl;
cout << "MyObj[" << b << "] struct vi size:" << MyObj[b].TheStructV[0].vi.size() << endl;
}
for (int i = 0; i < 3; i++) {
cout << "MyObj[" << i << "].vi:";
for (int j = 0; j < 5; j++) {
cout << MyObj[i].TheStructV[0].vi[j] << "-";
}
cout << endl;
}
return 0;
}
It works as expected, and the output is:
MyObj[0] struct vector size:1
MyObj[0] struct vi size:5
MyObj[1] struct vector size:1
MyObj[1] struct vi size:5
MyObj[2] struct vector size:1
MyObj[2] struct vi size:5
MyObj[0].vi:11-21-31-41-51-
MyObj[1].vi:12-22-32-42-52-
MyObj[2].vi:13-23-33-43-53-
However, if I change the code to this:
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
class MyClass
{
public:
struct mystruct {
vector<int> vi;
};
vector<mystruct> TheStructV;
void AddStructV() {
TheStructV.push_back(mystruct());
};
};
int main()
{
MyClass MyObj[3];
int idx = 1;
for (auto M : MyObj) {
M.AddStructV();
for (int i = 1; i <= 5; i++) {
M.TheStructV[M.TheStructV.size() - 1].vi.push_back(i * 10 + idx);
}
idx++;
}
for (int b = 0; b<3; b++) {
cout << "MyObj[" << b << "] struct vector size:" << MyObj[b].TheStructV.size() << endl;
cout << "MyObj[" << b << "] struct vi size:" << MyObj[b].TheStructV[0].vi.size() << endl;
}
idx = 1;
for (auto MC : MyObj) {
cout << "MyObj[" << idx - 1 << "].vi:";
for (auto thisStruct : MC.TheStructV) {
cout << thisStruct.vi[0] << "-";
cout << thisStruct.vi[1] << "-";
cout << thisStruct.vi[2] << "-";
cout << thisStruct.vi[3] << "-";
cout << thisStruct.vi[4] << "-";
}
cout << endl;
idx++;
}
return 0;
}
It compiles without problem, but I get an error when I run it, and the output is:
MyObj[0] struct vector size:0
The program is stuck here.
It seems that I am missing something. I even tried replacing auto M with MyClass M, but still the same problem.
This line will make a copy of your object
for (auto M : MyObj)
change it to a reference so you can modify it
for (auto& M : MyObj)
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.
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;