I have a very simple program where I ask the user if they want to print to screen or a file. Rather than create two sets of output sections, I thought I could switch a stream to either cout or an ofstream and then output to that stream. However, I'm getting screen output no matter what.
ostream &out = cout;
do
{
cout << "Write to file (f) or screen (s)?";
cin >> yes_or_no;
} while (yes_or_no != 'f' && yes_or_no !='s');
if (yes_or_no=='f')
{
ofstream out;
out.open("Report.txt");
cout << "Writing report to Report.txt" << endl;
system("pause");
}
out << "Day: Current Value ROI" << endl;
out << "------------------------------------------" << endl;
out << setw(5) << 0;
out << "$" << setw(20) << setprecision (2) << fixed << initial_value;
out << setw(12) << "1.00" << endl;
for (int day = 1 ; day < number_of_days ; day++)
{
current_value = generateNextStockValue(current_value, volatility, trend);
out << setw(5) << day;
out << setw(20) << setprecision (2) << fixed << current_value;
out << setw(12) << setprecision (2) << fixed << current_value / initial_value;
out << endl;
}
You could put all the writing logic inside a function, and let the caller decide which output stream to write to:
void do_the_stuff(std::ostream& os)
{
// write to os
os << "blah blah" ....
}
then
if (yes_or_no=='f')
{
ofstream out("Report.txt");
do_the_stuff(out);
} else {
do_the_stuff(std::cout);
}
Related
I'm currently writing a menu driven program in C++ and I'm having a little difficulty searching for a certain int in an Output file. My function looks like this.
int studentId;
int searchId;
double examGrade1, examGrade2, examGrade3;
ifstream readGrades;
do
{
cout << "Enter the student ID: ";
cin >> searchId;
if (searchId < 0 || searchId > 9999) {
cout << "Your student ID must be in between 0 and 9999! Try again...\n";
}
} while (searchId < 0 || searchId > 9999);
readGrades.open("grades.txt");
if (readGrades)
{
system("cls");
while (readGrades >> studentId >> examGrade1 >> examGrade2 >> examGrade3)
{
if (searchId == studentId)
{
cout << left
<< "Student ID\t" << "Exam 1\t" << "Exam 2\t" << "Exam 3\t" << endl;
cout << "======================================" << endl;
cout << left << setw(4) << studentId << "\t\t"
<< fixed << setprecision(2)
<< left << setw(5) << examGrade1 << "\t"
<< left << setw(5) << examGrade2 << "\t"
<< left << setw(5) << examGrade3 << endl;
system("pause");
break;
}
else
cout << "Entered ID not found";
}
}
else
{
cout << "Error opening file!\n";
}
cout << endl; }
Now the problem is the else statement. I am supposed to prompt to the user that a certain ID doesn't exist. But I don't know how to make the else statement only run once in the while statement. Every time I search a non-existing ID, it will say "Entered ID not found" for however many times it reads the inputs.
So the results look something like this.
No ID Found
At the same time, if I enter an ID that does exist but it's third in the file, it will look something like this. ID Found
I know logically what is happening, it keeps running the while loop for however many times. But I don't know how to deal with the problem. Any help to lead me to the right direction would be helpful. I'm new to coding/C++ and not too familiar with searching for something inside a file. Thank you!
The else block is in the wrong place. You need to update your logic such that you print that message only if the student ID is not found after going through the entire file. Which means, it has be outside the while loop.
if (readGrades)
{
bool found = false;
while (readGrades >> studentId >> examGrade1 >> examGrade2 >> examGrade3)
{
if (searchId == studentId)
{
cout << left
<< "Student ID\t" << "Exam 1\t" << "Exam 2\t" << "Exam 3\t" << endl;
cout << "======================================" << endl;
cout << left << setw(4) << studentId << "\t\t"
<< fixed << setprecision(2)
<< left << setw(5) << examGrade1 << "\t"
<< left << setw(5) << examGrade2 << "\t"
<< left << setw(5) << examGrade3 << endl;
found = true;
break;
}
}
if ( !found )
{
cout << "Entered ID not found";
}
}
Lets say you have a data file with multiple entries of struct type data
Based on the code number variable of one of the data entries,you are supposed to draw out the remaining variables of the structure.
Or maybe should I try to find the record number based on the scode?
then using the record number to find the size I need to skip from the beginning using seekg
char scode[MAX];
Subject M;
afile.open (fileName, ios::in | ios::out | ios::binary);
cout << "Enter Subject code: ";
cin >> scode;
cin.clear();
cin.ignore(100,'\n');
cout << endl << endl;
while (afile.read (reinterpret_cast <char *>(&M), sizeof (M)))
{
if (strcmp(scode,M.subCode) == 1)
{
cout << "Subject code not found" << endl;
cout << "----------------------------" << endl;
return;
}
else
{
afile.seekg(-strlen(M.subCode),ios::cur);
cout << "Subject Code: " << M.subCode << endl
<< "Subject Name: " << M.subTitle << endl;
cout << left << setw(8) << "Task"
<< left << setw(14) << "Title"
<< right << setw(7) << "Weight"
<< right << setw(7) << "Upon"
<< right << setw(7) << "Mark"
<< right << setw(12) << "Obtained"
<< endl << endl;
cout << setw (66) << setfill ('-') << "-" << endl;
cout << setfill (' ');
while (afile.read (reinterpret_cast <char *>(&M), sizeof (M)))
{
for (int i = 1; i <= M.noTask; i++)
{
cout << left << setw(8) << i
<< left << setw(14) << M.Task[i].title
<< right << setw(7) << M.Task[i].weight
<< right << setw(7) << M.Task[i].fullmark
<< right << setw(7) << M.Task[i].mark
<< right << setw(12) << M.Task[i].mark / M.Task[i].fullmark * M.Task[i].weight
<< endl;
}
}
}
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdlib.h>
using namespace std;
struct football_game
{
string visit_team;
int home_score;
int visit_score;
};
void printMenu();
int main()
{
int i, totalValues = 0;
ifstream inputFile;
string temp = "";
inputFile.open("games.txt");
if (!inputFile)
{
cout << "Error opening Input file!" << endl;
exit(101);
}
inputFile >> totalValues;
getline(inputFile, temp);
cout << " *** Football Game Scores *** " << endl << endl;
cout << " * Total Number of teams : " << totalValues << endl << endl;
football_game* records = new football_game[totalValues];
// while (!inputFile.eof())
// {// == NULL) {
for (i = 0; i < totalValues; i++)
{
getline(inputFile, records[i].visit_team);
cout << records[i].visit_team << endl;
inputFile >> records[i].home_score >> records[i].visit_score;
cout << records[i].home_score << " " << records[i].visit_score << endl;
getline(inputFile, temp);
}
//}
cout << endl;
int choice = 0;
int avg_home_Score = 0;
int avg_visit_Score = 0;
printMenu(); // prints menu
cout << "Please Enter a choice from the Menu : ";
cin >> choice;
cout << endl << endl;
while (true)
{
switch (choice)
{
case 1:
cout << " Score Table " << endl;
cout << " ***********************" << endl << endl;
cout << " VISIT_TEAM"
<< " "
<< " HIGH_SCORE"
<< " "
<< "VISIT_SCORE " << endl;
cout << " -----------"
<< " "
<< "-----------"
<< " "
<< "------------" << endl;
for (int i = 0; i < totalValues; i++)
{
cout << '|' << setw(18) << left << records[i].visit_team << " " << '|'
<< setw(7) << right << records[i].home_score << " " << '|' << setw(7)
<< right << records[i].visit_score << " " << '|' << endl;
}
cout << endl << endl << endl;
break;
case 2:
{
string team_name;
cout << "Enter the Team Name : ";
cin >> team_name;
for (int i = 0; i < totalValues; i++)
{
if (records[i].visit_team == team_name)
{
cout << " VISIT_TEAM"
<< " "
<< " HIGH_SCORE"
<< " "
<< "VISIT_SCORE " << endl;
cout << " -----------"
<< " "
<< "-----------"
<< " "
<< "------------" << endl;
cout << '|' << setw(18) << left << records[i].visit_team << " " << '|'
<< setw(7) << right << records[i].home_score << " " << '|'
<< setw(7) << right << records[i].visit_score << " " << '|'
<< endl;
}
}
cout << endl;
break;
}
case 3:
{
for (int i = 0; i < totalValues; i++)
avg_home_Score += records[i].home_score;
cout << "Average home_score: " << (avg_home_Score / totalValues) << endl << endl;
break;
}
case 4:
{
for (int i = 0; i < totalValues; i++)
avg_visit_Score += records[i].visit_score;
cout << "Average visit_score: " << (avg_visit_Score / totalValues) << endl << endl;
break;
}
default:
{
cout << "Please enter valid input !!" << endl;
break;
}
}
printMenu();
cin >> choice;
}
return 0;
}
void printMenu()
{
cout << " Menu Options " << endl;
cout << " ================ " << endl;
cout << " 1. Print Information of all Games[Table Form] " << endl;
cout << " 2. Print Information of a Specific Game " << endl;
cout << " 3. Print Average points scored by the Home Team during season" << endl;
cout << " 4. Print Average points scored against the Home Team" << endl << endl << endl;
}
Here is the input file i am using
games.txt
5
SD Mines
21 17
Northern State
10 3
BYU
10 21
Creighton
14 7
Sam Houston State
14 24
When i am using the 2nd option (Print Information of a Specific Game) from the output screen,
it ask me to enter the team name and when i enter the team-name.
For example: SD Mines it gives me an error, but when I enter the team-name with no space like: BYU it works fine for me.
cin >> team_name;
Takes the input only upto space.
You might want to use cin.getline() for taking space separated strings as input.
A small program demonstrating the same :
#include <iostream>
#include <string>
int main ()
{
std::string name;
std::cout << "Please, enter your full name: ";
std::getline (std::cin,name);
std::cout << "Name is : , " << name << "!\n";
return 0;
}
std::cin ignores whitespaces by default.
To include spaces in your input try :
getline(cin, team_name);
This would pick up all the characters in a line until you press enter. This is available in
#include<string>
You need to flush the std::cin buffer after reading the choice:
#include <limits>
//...
cin >> choice;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
Refer to this question for detailed explanation.
Also, if you want to read strings with spaces from the standard input, replace this:
cin >> team_name;
with this:
getline(cin, team_name);
as already mentioned in other answers. No need to flush std::cin this time, since you have already read the full line.
Finally, remove extra newlines from your games.txt:
5
SD Mines
21 17
Northern State
...
Doing an assignment and struggling hard. I think I've narrowed down my problem to the for loop. Can anyone explain how to fix this? I can't find an answer on google or here that's helping me get it. I have to make an array of some data files I was given. Then use a for loop to display the results. The input is:
1/8/2016,98.550003,96.959999,70798000
1/11/2016,98.970001,98.529999,49739400
1/12/2016,100.550003,99.959999,49154200
etc.
The expected output should be clean numbers like above.
The observed output is a mess of numbers that's way too big.
//Variable Declaration
const int SIZE = 400;
double stockOpen[SIZE];
double stockClose[SIZE];
double stkCloseAVG=0;
double minStkClose;
double maxStkClose;
int stockVolume[SIZE];
int i = 0;
string name = "r";
string stockDate[SIZE];
string stockName;
string filename;
ifstream in;
string stkDate, stkOpen, stkClose, stkVol;
int actSize;
cout << "Welcome to " << name << "'s stock majigger thingy!" << endl;
cout << "Please enter the stock name (aapl; spy)" << endl;
cin >> stockName;
filename = stockName + ".table.csv";
in.open(filename.c_str());
if (!in)
{
cout << "File Error! Please try again! I BELIEVE IN YOU, LOVE!" << endl;
system("pause");
exit(-1);
}
while (!(in.eof()) && i < SIZE)
{
getline(in, stkDate, ',');
getline(in, stkOpen, ',');
getline(in, stkClose, ',');
getline(in, stkVol, '\n');
i++;
// Check:cout << stkDate << endl <<endl<< stkOpen<<endl << stkClose<<endl << stkVol;
//system("pause");
}
actSize = i;
//system("clr");
for (int i=0; i < actSize; i++) // <- Need help here
{
cout << "Stock Daily Performance Report -" << stockName << endl;
cout << setw(10) << "Date" << setw(7) << "Open" << setw(7) << "Close" << setw(11) << "Volume" << endl;
cout << setw(10) << stockDate[i] << fixed << setprecision(2) << setw(7) << stockOpen[i] << setw(7) << stockClose[i] << fixed << setprecision(0) << setw(11) << stockVolume[i] << endl;
stkCloseAVG= stkCloseAVG + stockClose[i];
minStkClose = stockClose[1];
maxStkClose = stockClose[1];
if (stockClose[i] < minStkClose)
minStkClose = stockClose[i];
if (stockClose[i] > maxStkClose)
maxStkClose = stockClose[i];
}
cout << "Stock Price" << endl;
cout << endl;
cout << "Average" << setw(5) << stkCloseAVG << endl;
cout << "Minimum" << setw(5) << minStkClose << endl;
cout << "Maximum" << setw(5) << maxStkClose << endl;
system("pause");
return 0;
I have a pointer to object error type for the variable "carrierTime" i have created. If i make this an array, carrierTime becomes an error in the first if statement, however if i leave it without any array i get an error on the last line of the code where i have used carrierTime in a multiplication.
can anyone help??
platform used:visual studios
#include "AMcore.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main()
{
cout << "Amplitude Modulation Coursework" << endl;
cout << "Name: Mohammad Faizan Shah" << endl;
cout << "Student ID: 5526734 \n\n\n" << endl;
std::ifstream file,file2;
string filename1,filename2;
int rowCounter = 0;
double informationTime;
double informationAmplitudeAmount[361];
long double carrierTime;
double carrierAmplitudeAmount[361];
double totalAmplitudeAmount[1000];
int plotPoint;
cout << "Please enter the filename of the Carrier wave \n" << endl;
cin >> filename1;
file.open("carrier.txt");
if (file.is_open())
{
file >> carrierTime;
while (!file.fail())
{
cout << "row" << setw(3) << rowCounter;
cout << " Time = " << setw(5) << carrierTime;
file >> carrierAmplitudeAmount[rowCounter];
rowCounter++;
if (!file.fail())
{
cout << " Carrier signal= " << setw(5) << carrierAmplitudeAmount;
file >> carrierTime;
}
cout << endl;
}
if (file.eof())
cout << "Reached the end of file marker" << endl;
else
cout << "Error whilst reading input file" << endl;
}
else
{
cout << "Error opening input file, ";
cout << "check carrier.txt exists in the current directory." << endl;
}
file.close();
cout << "\n\n" << endl;
cout << "Please enter the filename of the information wave \n\n\n" << endl;
cin >> filename2;
file2.open("information.txt");
if (file2.is_open())
{
file2 >> informationTime;
while (!file2.fail())
{
cout << "row" << setw(3) << rowCounter;
cout << " Time = " << setw(5) << informationTime;
file2 >> informationAmplitudeAmount[361];
rowCounter++;
if (!file2.fail())
{
cout << " Carrier signal= " << setw(5) << informationAmplitudeAmount;
file2 >> informationTime;
}
cout << endl;
}
if (file2.eof())
cout << "Reached the end of file marker" << endl;
else
cout << "Error whilst reading input file" << endl;
}
else
{
cout << "Error opening input file, ";
cout << "check carrier.txt exists in the current directory." << endl;
}
file.close();
cout << "Reading from txt file has completed" << endl << endl;
cout << "\n\n" << endl;
cout << "\n\n" << endl;
cout << "please enter number of sample points to plot:| \n" << endl;
do{
cin >> plotPoint;
if (plotPoint <= 361)
{
cout << "\n plotting the graph.\n" << endl;
}
else if (plotPoint > 361)
{
cout << "Value is too high.. Try value lower than 361\n" << endl;
}
} while (plotPoint > 361);
cout << "row" << setw(3) << rowCounter;
file >> carrierAmplitudeAmount[361];
rowCounter++;
plotPoint = 361 / plotPoint;
cout << " Time \| Amplitude Modulation plot\n------------+--------------------------------------------------\n";
totalAmplitudeAmount[0] = carrierAmplitudeAmount[0] * informationAmplitudeAmount[0];
cout << setw(6) << carrierTime << setw(4) << "\|" << setw(48) << "*" << totalAmplitudeAmount[0] << endl;
for (int i = 1; i <= 361; i = i + plotPoint) {
totalAmplitudeAmount[i] = informationAmplitudeAmount[i] * carrierAmplitudeAmount[i];
int y = totalAmplitudeAmount[i] * 22;
cout << setw(6) << carrierTime[i++] << setw(4) << "\|" << setw(26 + y) << "*" << totalAmplitudeAmount[i] << endl;
}
cout << "End of program" << endl;
system("pause");
return 0;
}
cout << setw(6) << carrierTime[i++] << setw(4) << "\|" << setw(26 + y) << "*" << totalAmplitudeAmount[i] << endl;
carrierTime[i++] does not look correct. The variable is not defined as a pointer.
Also, proper debugging would help you catch these errors for yourself.