Reading next line from file - c++

So the program is supposed to read from the file, which has 4-5 lines of information on it. I can read the first line into the program, and process it through the various algorithms, but I'm not sure how to loop the next line into it and process it as well, again and again until the end of the file. Thank you very much for reading and all input is appreciated. Here is the entire program, with the text read in from file at the bottom.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inputFile;
ofstream invoicefile;
string name, author, isbn, customerid, filename, fictionoutput, genreoutput;
char booktype, genre;
bool fictionvalue;
double initial_total, tax_price, subtotal, totalprice, price;
int fee, quantity;
const double tax(0.07);
cout << "Enter name of file.\n";
cin >> filename;
cout << "Opening file \n";
inputFile.open(filename);
if (inputFile.is_open()) {
inputFile >> customerid >> name >> author >> isbn >> price >> quantity >> booktype >> genre;
//QUANTITY FEE CODING BLOCK
if (quantity > 50) {
fee = 50;
}
else if (quantity >= 15 && quantity <= 19) {
fee = 40;
}
else if (quantity >= 10 && quantity <= 14) {
fee = 30;
}
else if (quantity >= 5 && quantity <= 10) {
fee = 20;
}
else if (quantity < 5) {
fee = 10;
}
//BOOKTYPE CODING BLOCK (FICTION or NON-F)
if (booktype == 'F') {
fictionvalue = true;
}
else if (booktype == 'N') {
fictionvalue = false;
}
else {
cout << "INVALID";
}
//BOOKTYPE INTO STRING OUTPUT
if (fictionvalue = true) {
fictionoutput = "Fiction";
}
else if (fictionvalue = false) {
fictionoutput = "Non-Fiction";
}
//GENRE TYPE INTO STRING OUTPUT
if (genre == 'R') {
genreoutput = "Romance";
}
else if (genre == 'D') {
genreoutput = "Drama";
}
else if (genre = 'M') {
genreoutput = 'M';
}
else {
cout << "Invalid entry\n";
}
//NO FEE EXCEPTION
if (booktype == 'N' && genre == 'R') {
fee = 0;
}
//CALCULATION OF PRICE + TAX CODING BLOCK
initial_total = (price*quantity);
tax_price = (initial_total * tax);
subtotal = (initial_total + tax_price);
totalprice = (subtotal + fee);
//OUTPUT TO FILE/CONSOLE CODING BLOCK
cout << "-----------------------------------------" << endl;
cout << "Order Invoice" << endl;
cout << "Customer ID: " << customerid << endl;
cout << name << " " << author << " " << fictionoutput << " " << genreoutput << " " << quantity << "#" << price << "Subtotal: " << endl; //add subtotal price
//cout << "Total book sales: " <<
cout << "Tax: " << tax_price << endl;
cout << "Subtotal: " << subtotal << endl;
cout << "Fee: " << fee << endl;
cout << "Total Price: " << totalprice << endl;
cout << "-----------------------------------------" << endl;
system("pause");
}
}
TEXT SAMPLE
1234 Dog_Strategy Henry_Moreno 3-598-21500-2 12.99 5 N M
6789 Companion_Kicked_Me_Out Lorraine_Johnson 3-598-21599-1 24.99 3 F R
3444 Mime_On_My Journey Kristy_Wahl 3-699-21500-8 6.75 10 N D
4455 Damaged_By_The_Joke Henry_Christopher 3-598-21500-2 12.99 4 N R

Maybe try using a loop like this:
// Create an empty string
std::string line;
// Start a loop that will get a line from the file and input it in our string
// this loop will keep going until the getline fails, i.e. end of file.
while (std::getline(fileName, line))
{
CODE
}

you can put a while loop that will run until the program saw the end of file
while(!EOF)
{your code here}
and always dont forget to close the file you opened

Related

Trying to have error correction while prompting to run program again

New to C++. I have a homework program I am programming. It is all but done, but our teacher wants us to add error catching to the program.
The issue arises in the code for asking the user to run again. I use a while loop to monitor a variable until it changes.
This works:
#include <iostream>
using namespace std;
int main() {
char runAgainYN;
while ( toupper(runAgainYN != 'N' ) {
// Do some stuff here!
cout << "Would you like to run again?";
cin >> runAgainYN;
}
return 0;
}
It keeps looping the program until runAgain is equal to 'N', then stops. Now, I modified the program to utilize some error correction for the question about running the program again, to limit the user to only entering Y or N. Here is the updated code:
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char runAgainYN;
bool runAgain = true;
while ( runAgain ) {
// Do some stuff here!
bool validResponse = false;
while ( !validResponse ) {
cout << "Would you like to run the program again (Y/N): ";
cin >> runAgainYN;
if ( toupper(runAgainYN) == 'Y' ) {
validResponse = true;
cin.ignore();
}
else if ( toupper(runAgainYN) == 'N' ) {
runAgain = false;
validResponse = true;
cin.ignore();
}
else {
cout << "INVALID RESPONSE" << endl;
}
}
}
return 0;
}
Here is where the problem arises. If the user enters 'N', the program exits with code 0, and if the user enters anything but Y or N, the invalid response triggers and asks for the input again. But, if the user enters Y, the program exits with code -1. Huh? I tried a different approach, with the same result:
#include <iostream>
#include <cctype>
using namespace std;
int main() {
char runAgainYN;
do {
// Do some stuff here!
bool validResponse = false;
while ( !validResponse ) {
cout << "Would you like to run the program again (Y/N): ";
cin >> runAgainYN;
if ( toupper(runAgainYN) == 'Y' ) {
validResponse = true;
cin.ignore();
}
else if ( toupper(runAgainYN) == 'N' ) {
runAgain = false;
validResponse = true;
cin.ignore();
}
else {
cout << "INVALID RESPONSE" << endl;
}
}
}
while ( runAgain );
return 0;
}
Any help guys? Thanks!!!
OK, so it seems to be something in the actual program causing it. Here's the source code:
#include <iostream>
#include <string>
#include <string.h>
#include <iomanip>
#include <cctype>
#include <limits>
#include <algorithm>
#include <fstream>
using namespace std;
void cls();
void printLine( int length );
void showCurrency( double dv, int width = 14 );
int main() {
string itemName[999][2];
double itemPrice[999][3];
double salesTotal = 0.0;
double salesTax = 0.0;
double totalTax = 0.0;
double taxRate = 0.0;
double grandTotal = 0.0;
double test = 0.0;
int numLines = 0;
string readLine;
string temp;
ifstream fileIn;
string menuHeader = "Sales Receipt from File";
char runAgainYN;
bool runAgain = true;
do { // Loop until runAgain false
// Open the file and count the number of lines, then close for next operation:
fileIn.open("cost.txt");
while (!fileIn.eof()) {
fileIn >> temp;
numLines++;
temp = "";
}
fileIn.close();
// Open the file and move the data into the arrays, then close:
fileIn.open("cost.txt");
for ( int i = 0; i < numLines; i++) {
fileIn >> itemName[i][1] >> itemPrice[i][1];
}
fileIn.close();
cls();
numLines = numLines / 2;
cout << "/";
printLine(80);
cout << "\\" << endl;
cout << "|" << setw(81) << "|" << endl;
cout << "|" << setw(41 + (menuHeader.length() / 2)) << menuHeader << setw(40 - (menuHeader.length() / 2)) << "|" << endl;
cout << "|" << setw(81) << "|" << endl;
cout << "\\";
printLine(80);
cout << "/" << endl << endl;
cout << "Enter the sales tax percentage (ie for 6% enter 6): ";
// Ask for taxRate and error check:
while (!(cin >> taxRate)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "INVALID RESPONSE" << endl << "Please enter a number: ";
}
cout << endl;
salesTax = taxRate / 100; // Convert sales tax to percentage
for (int i = 0; i < numLines; i++ ) { // Set the running tax amounts
itemPrice[i][2] = itemPrice[i][1] * salesTax;
salesTotal = salesTotal + itemPrice[i][1];
totalTax = totalTax + itemPrice[i][2];
}
//totalTax = salesTotal * salesTax; // Calculate tax
grandTotal = salesTotal + totalTax; // Calculate grand total
// Output:
cls();
cout << "/" << setfill('-') << setw(63) << "-" << "\\" << setfill(' ') << endl;
cout << "| SALES RECEIPT |" << endl;
cout << "|" << setfill('-') << setw(63) << "-" << "|" << setfill(' ') << endl;
cout << "| " << left << setw(32) << "Sales item" << setw(13) << right << "Price" << setw(18) << "Tax |" << endl;
cout << "|" << setfill('-') << setw(63) << "-" << "|" << setfill(' ') << endl;
for ( int i = 0; i <= numLines - 1; ++i ){
cout << "| " << left << setw(32) << itemName[i][1] << "$" << setw(12) << setprecision(2) << fixed << right << itemPrice[i][1] << setw(5) << "$" << setw(11) << itemPrice[i][2] << " |" << endl;
}
cout << "|" << setfill('-') << setw(63) << "-" << "|" << setfill(' ') << endl;
cout << "| Total Sales" << setw(36);
showCurrency(salesTotal);
cout << " |" << endl;
cout << "| Sales Tax (" << setprecision(0) << fixed << taxRate << "%)" << setw(33);
showCurrency(totalTax);
cout << " |" << endl;
cout << "|" << setfill('-') << setw(63) << "-" << "|" << setfill(' ') << endl;
cout << "| Grand Total" << setw(36);
showCurrency(grandTotal);
cout << " |" << endl;
cout << "\\" << setfill('-') << setw(63) << "-" << "/" << setfill(' ') << endl;
cout << endl;
// Clear vars and array for next run:
salesTax = 0.0;
totalTax = 0.0;
salesTotal = 0.0;
grandTotal = 0.0;
memset(itemPrice, 0, sizeof(itemPrice));
memset(itemName, 0, sizeof(itemName));
// Ask if program is to be run again:
bool validResponse = false;
while ( !validResponse ) {
cout << "Would you like to enter a new tax rate (Y/N): ";
cin >> runAgainYN;
if ( toupper(runAgainYN) == 'Y' ) {
validResponse = true;
cin.ignore();
}
else if ( toupper(runAgainYN) == 'N' ) {
runAgain = false;
validResponse = true;
cin.ignore();
}
else {
cout << "INVALID RESPONSE" << endl;
}
}
}
while ( runAgain == true );
return 0;
}
void printLine( int length ) {
for ( int i = 0; i < length; i++ ) {
cout << "=";
}
}
void cls() {
// check OS and run correct clear screen (I do some of my coding in Linux :)
#if (defined (_WIN32) || defined (_WIN64))
system("CLS");
#elif (defined (LINUX) || defined (__linux__))
system("clear");
#endif
}
void showCurrency(double dv, int width){
/* Credit where credit is due:
* The following code snippet was found at https://arachnoid.com/cpptutor/student3.html
* Copyright © 2000, P. Lutus. All rights reserved.
*/
const string radix = ".";
const string thousands = ",";
const string unit = "$";
unsigned long v = (unsigned long) ((dv * 100.0) + .5);
string fmt,digit;
int i = -2;
do {
if(i == 0) {
fmt = radix + fmt;
}
if((i > 0) && (!(i % 3))) {
fmt = thousands + fmt;
}
digit = (v % 10) + '0';
fmt = digit + fmt;
v /= 10;
i++;
}
while((v) || (i < 1));
cout << unit << setw(width) << fmt.c_str();
}
And here is the contents of 'cost.txt':
Books 45.01
Pens 21.03
Pencils 10.90
Hats 50.00
Caps 800.00
Food 1.00
OK looks like i got it. The file operations were within the do loop. I moved them outside of the loop, and it all works. Thanks!

Reading numbers from text and outputting average

So I am working to read text from a file (line by line) and output the ID, average of 4 grades following the ID, and the letter grade. So the letter grade for any average grade of 50 or above is S, anything below 50 is a U, and 2 excused classes results in the letter grade I. (No S or U if more than or equal to 2 excused).
So lets say file has the numbers:
42 50 51 57 52
48 90 -1 60 -1
40 46 -1 59 45
47 50 -1 49 50
The output should look something like this:
ID=42 Avg=52.5 Grade=S
ID=48 Excused=2 Grade=I
ID=40 Avg=50.0 Grade=S
ID=47 Avg=49.7 Grade=U
Number of Grades of Type
S U I
2 1 1
This is the output I am receiving from my code
It is reading all the numbers, but i need it to read the first number as ID and following 4 numbers as grade.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream in;
ofstream results;
string filename;
char grade;
int S = 0, U = 0, I = 0, i = 0, ID, excused = 0, avg;
double allscores = 0;
cout << "Enter the name of the file that has the scores of students: " << endl;
cin >> filename;
cout << "Enter the number of scores for each student: " << endl;
cin >> ID;
in.open(filename);
results.open("results.txt");
if (in)
{
while (in >> ID)
{
int first = 0
for (i = 0; i<=4; i++)
{
if (first == -1)
excused++;
else
allscores += first;
}
if (first > 4)
{
avg = allscores / (4 - excused);
if (avg >= 50.0)
{
grade = 'S';
S++;
cout << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
else
{
grade = 'U';
U++;
cout << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
}
else
{
grade = 'I';
I++;
cout << "ID=" << ID << " Excused=" << excused << " Grade =" << grade << endl;
}
}
}
else
{
cout << "Couldn't open file\n";
}
cout << "Number of Grades of Type" << endl;
cout << "S " << "U " << "I" << endl;
cout << S << " " << U << " " << I << endl;
in.close();
results.close();
system("pause");
return 0;
}
Your variable int first=0 is not being assigned any value other than 0 in your code so the statement if(first>4) will always be false and result the output your are getting.
You can do something like this:
while (in >> ID)//this is supposed to get the ID of each student, in order for that to happen you need to read all the 4 scores inside this loop before coming here and reading the next ID,otherwise everything will read as an ID
{
int first = 0
excused=0;//you need to reset excused on every iteration
allscores=0;//you need to reset allscore on every iteration
for (i = 0; i<4; i++)
{//here you need to get all the 4 scores
in>>first;//get each score in first
if (first == -1)
excused++;
else
allscores += first;
}
if(excused<2)//instead of if(first>4)
...//do your calculation for average score
else
...//set the grade to 'I'...
}
Here is my final solution:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream in;
ofstream results;
string filename;
char grade;
int S = 0, U = 0, I = 0, i = 0, ID, excused = 0, avg;
double allscores = 0;
cout << "Enter the name of the file that has the scores of students: " << endl;
cin >> filename;
cout << "Enter the number of scores for each student: " << endl;
cin >> ID;
in.open(filename);
results.open("results.txt");
if (in)
{
while (in >> ID)
{
int first = 0;
excused = 0;
allscores = 0;
for (i = 0; i < 4; i++)
{
in >> first;
if (first == -1)
excused++;
else
allscores += first;
}
if (excused < 2)
{
avg = allscores / (4 - excused);
if (avg >= 50.0)
{
grade = 'S';
S++;
results << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
else
{
grade = 'U';
U++;
results << "ID=" << ID << " Avg=" << avg << " Grade =" << grade << endl;
}
}
else
{
grade = 'I';
I++;
results << "ID=" << ID << " Excused=" << excused << " Grade =" << grade << endl;
}
}
}
else
{
cout << "Couldn't open file\n";
}
results << "Number of Grades of Type" << endl;
results << "S " << "U " << "I" << endl;
results << S << " " << U << " " << I << endl;
in.close();
results.close();
system("pause");
return 0;
}
After the code I have it output to a file named "results".
Thanks for the help. I guess my while loop was the biggest mistake.
Especially not adding in the in >> first portion.

Difficulties with saving a text file using ofstream

Right now my problem seems to be focused on the saveFile function.
I will post the entire program here, so dont be ired when see a whole bunch of code... just look at the saveFile function at the bottom... I am posting all the code JUST IN CASE it will help you help me solve my problem.
Now for defining the apparent problem to you all: I can edit the file throughout the life of the console app with the updateSale function as I run it, but when I use the saveFile function and put in 'y' to save, the differences that are visible after using the updateSales function DO NOT get saved to the actual sales file called "salespeople.txt" and I do not understand why.
this is what the salespeople.txt looks like:
Schrute 25000
Halpert 20000
Vance 19000
Hudson 17995.5
Bernard 14501.5
now here is the program:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
//variables--------------------------------------------------------
int lineCount = 0;
//prototypes-------------------------------------------------------
int getIndexLargest(string[], double[]);
void displaySalesPeople(string[], double[]);
bool readSalesFile(string[], double[]);
void updateSales(string[], double[]);
int saveFile(string, string[], double[], int);
int main()
{
string fileName;
int arrayLength;
ifstream readSales;
string salesPersonName[5];
double saleAmount[5];
bool flag = false;
int options;
do
{
cout << "1) Open sales person file. "<< endl;
cout << "2) Display sales person information. "<< endl;
cout << "3) Update sales. " << endl;
cout << "4) Get best sales person. " << endl;
cout << "5) Exit. " << endl;
cout << "Please enter a number 1-5 to select an option." <<endl;
cin >> options;
if(options == 1)
{
flag = readSalesFile(salesPersonName, saleAmount);
}
else if(options == 2)
{
if(flag == false)
{
cout << "Please open sales file before selecting this option. Try again" << endl;
}
else
displaySalesPeople(salesPersonName, saleAmount);
}
else if(options == 3)
{
if(flag == false)
{
cout << "Please open sales file before selecting this option. Try again" << endl;
}
else
updateSales(salesPersonName, saleAmount);
}
else if(options == 4)
{
if(flag == false)
{
cout << "Please open sales file before selecting this option. Try again" << endl;
}
getIndexLargest(salesPersonName, saleAmount);
}
else if(options == 5)
{
char choice;
cout << "Enter character y to save... anything else will exit without saving: " << endl;
cin >> choice;
if(choice == 'y')
{
saveFile(fileName, salesPersonName, saleAmount, arrayLength);
cout << "File saved. " << endl;
}
else
{
cout << "closing program" << endl;
}
}
}
while(options != 5);
return 0;
}
//functions---------------------------------
bool readSalesFile(string salesPersonName[], double saleAmount[])
{
bool flag = false;
ifstream readSales;
string fileName;
cout << "Please enter the path to your sales people file: ";
getline(cin, fileName);
readSales.open(fileName.c_str());
while(readSales.fail())
{
cout << "Failed. Please enter the path to your sales file again: ";
getline(cin, fileName);
readSales.open(fileName.c_str());
}
if(readSales.good())
{
flag = true;
cout << lineCount;
string name = " ";
double amount =0.00;
int i = 0;
while(!readSales.eof())
{
readSales >> name;
readSales >> amount;
salesPersonName[i] = name;
saleAmount[i] = amount;
i++;
}
for(i = 0; i < 5; i++)
{
cout << "Sales person name: " << salesPersonName[i] << endl;
cout << "Sale amount: $" << saleAmount[i] << endl;
}
readSales.close();
}
readSales.close();
return flag;
}
void displaySalesPeople(string salesPersonName[], double saleAmount[])
{
for(int i = 0; i < 5; i++)
{
cout << "Sales person name: " << salesPersonName[i] << endl;
cout << "Sale amount: $" << saleAmount[i] << endl;
}
}
void updateSales(string salesPersonName[], double saleAmount[])
{
bool flag = false;
string findName;
double moneyAmount;
cout << "Enter name of sales person you want to modify: " << endl;
cin >> findName;
for(int i = 0; i < 5; i++)
{
if(findName == salesPersonName[i])
{
cout << "Enter the sale amount you would like to modify: " << endl;
cin >> moneyAmount;
saleAmount[i] += moneyAmount;
cout << saleAmount[i] << endl;
flag = true;
}
}
if(flag == false)
{
cout << " name not found" << endl;
}
}
int getIndexLargest(string salesPersonName[], double saleAmount[])
{
ifstream readSales;
while(!readSales.eof())
{
double largestSale = 0.00;
string largestSalesPerson;
int i = 0;
lineCount++;
readSales >> salesPersonName[i];
readSales >> saleAmount[i];
if(saleAmount[i] > largestSale)
{
largestSale = saleAmount[i];
largestSalesPerson = salesPersonName[i];
}
cout << "Best sales person : "<< largestSalesPerson << " $" <<setprecision(2)<<fixed<< largestSale << endl;
}
}
int saveFile(string fileName, string salesPersonName[], double saleAmount[], int arrayLength)
{
ofstream saveFile(fileName.c_str());
saveFile.open(fileName.c_str());
for(int i = 0; i < 5; i++)
{
saveFile << salesPersonName[i] << " " << saleAmount[i] << endl;
}
saveFile.close();
return 0;
}
You are trying t open your file twice:
ofstream saveFile(fileName.c_str()); // this opens the file
saveFile.open(fileName.c_str()); // so does this
That will put the file in an error state so no writing will happen.
Just do this:
ofstream saveFile(fileName.c_str()); // this opens the file
And that should work.
Or else you can do this:
ofstream saveFile; // this does not open the file
saveFile.open(fileName.c_str()); // but this does
And that should work too.

C++ Input Into Structure: _getch()

In C++, I'm trying to input movie's names and years of releasing and store them in a database/structure. Before I ask for the titles and years to be inputted. I have the user log on with credentials. In this case, the username is "rusty" and the password is "rusty".
The issue I'm having is the after the credentials are verified, the first movie title to input into the database/structure is skipped. I believe this has something to do with me using the _getch function, but I'm not totally sure.
My code is below. My output looks like this:
Please enter your username
rusty
Please enter your password
Access granted! Welcome rusty
Enter title: Enter year: (input movie year)
Enter title: (input movie title)
Enter year: (input movie year)
Enter title: (input movie title)
....
#include <iostream>
#include <string>
#include <sstream>
#include <conio.h>
using namespace std;
//function prototype
int username_and_pass();
#define NUM_MOVIES 6
struct movies_list{
string title;
int year;
}films[NUM_MOVIES];
// prototype with function declaration
void sort_on_title(movies_list films[], int n)
{
movies_list temp;
for (int i = 0; i < n - 1; i++)
{
if (films[i].title>films[i + 1].title)
{
temp = films[i];
films[i] = films[i + 1];
films[i + 1] = temp;
}
}
}// end of sort_on_title function
void printmovie(movies_list movie)
{
cout << movie.title;
cout << " (" << movie.year << ") \n";
}
void search_on_title(movies_list films[], int n, string title)
{
bool flag = false;
for (n = 0; n < NUM_MOVIES; n++)
{
if (films[n].title == title)
{
cout << "Title: " << films[n].title << endl;
cout << "Year of Release: " << films[n].year << endl;
cout << "\n";
flag = true;
}
}
if (flag == false)
cout << "Search on title not found!" << endl;
}// end of search_on_title function
void search_on_year(movies_list films[], int n, int year)
{
bool flag = false; // check on existence of record
for (n = 0; n < NUM_MOVIES; n++)
{
if (films[n].year == year) // display if true
{
cout << "Title: " << films[n].title << endl;
cout << "Year of Release: " << films[n].year << endl;
cout << "\n";
flag = true;
}
}
if (flag = false)
cout << "Search on title not found!" << endl;
}// end of search_on_title function
int menu()
{
int choice;
cout << " " << endl;
cout << "Enter 1 to search on titles " << endl;
cout << "Enter 2 to search on years " << endl;
cin >> choice;
cout << "\n";
return choice;
}// end of menu function
int username_and_pass()
{
string uName;
string password;
int value;
char ch;
cout << "Please enter your username\n";//"rusty"
cin >> uName;
cout << "Please enter your password\n";//"rusty"
ch = _getch();
while (ch != 13)//As long as the user doesn't press Enter
{//(enter is ASCII code 13) continue reading keystrokes from the screen.
password.push_back(ch);
cout << '*';
ch = _getch();
}
if (uName == "rusty" && password == "rusty")
{
cout << "\n\nAccess granted! Welcome " << uName << "\n\n" << endl;
value = 1
}
else
{
cout << "Invalid credentials" << endl;
value = 0;
}
return value;
}// end of username_and_pass function
int main()
{
string mystr;
int n;
string response;
int value = 0;
do
{
value = username_and_pass();
} while (value==0);
if(value==1)
{
for (n = 0; n < NUM_MOVIES; n++)
{
cout << "Enter title: ";
getline(cin, films[n].title);
cout << "Enter year: ";
getline(cin, mystr);
stringstream(mystr) >> films[n].year;
}
//sorts records
sort_on_title(films, NUM_MOVIES);
cout << "\nYou have entered these movies:\n";
for (n = 0; n < NUM_MOVIES; n++)
printmovie(films[n]);
//menu
int choice = 0;
choice = menu();
if (choice == 1)
{
string searchTerm;
cout << "What is the movie you want to search for? " << endl;
cin >> searchTerm;
cout << " " << endl;
search_on_title(films, NUM_MOVIES, searchTerm);
}
else
{
int searchTermYear;
cout << "What is the year you want to search for? " << endl;
cin >> searchTermYear;
cout << " " << endl;
search_on_year(films, NUM_MOVIES, searchTermYear);
}
cout << "Would you like to query the database again? (Y/N)" << endl;
cin >> response;
if (response == "Y" || "y")
{
choice = menu();
if (choice == 1)
{
string searchTerm;
cout << "What is the movie you want to search for? " << endl;
cin >> searchTerm;
cout << " " << endl;
search_on_title(films, NUM_MOVIES, searchTerm);
}
else
{
int searchTermYear;
cout << "What is the year you want to search for? " << endl;
cin >> searchTermYear;
cout << " " << endl;
search_on_year(films, NUM_MOVIES, searchTermYear);
}
}
}
return 0;
}
Flush all the content's of input buffer.
Please go to following link to flush contents of input buffer.
https://stackoverflow.com/a/7898516/4112271
I am not sure what causing you this problem.But can you try using cin.clear(). Place it before you ask for input of title.
cin.clear();
cout << "Enter title: ";
getline(cin, films[n].title);
cout << "Enter year: ";
getline(cin, mystr);
stringstream(mystr) >> films[n].year;

How do I write multiple output from a loop?

I got this program to calculate the grades to its corresponding letter grade, and I got it to loop as many times as the user wants to output. However, for some reason it only writes the last known output to its text file. Can anyone tell me what I am doing wrong here?
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
int weighted1 = 0;
int weighted2 = 0;
int weighted3 = 0;
int weighted4 = 0;
int weighted_average = 0;
const int MAX = 20;
int flag = 0;
int choice;
double sum = 0;
double average = 0;
char name [10];
char letter;
char file [MAX];
int num = 0;
int count = 0;
int main( )
{
//Initiate input/output stream
std::ifstream in_stream;
std::ofstream out_stream;
in_stream.open("grade.txt");
out_stream.open("finalgrade.dat");
double first, second, third, fourth;
in_stream >> first >> second >> third >> fourth >> name;
//std::cout >> " 1: " >> first >> " 2: " >> second >>
double grade = 0.0;
grade = (first + second + third + fourth)/4;
//Gives user the choice of reading student records from keyboard or file
bool menu = true;
while (menu != false)
{
std::cout << "Would you like to open as keyboard or file?" << '\n';
std::cout << "1. keyboard" << '\n';
std::cout << "2. file" << '\n';
std::cin >> choice;
switch (choice)
{
//Enter the number students the grades will enter
case 1:
std::cout << "How many students? ";
std::cin >> num;
for(count =0; count < num; count++)
{
{
std::cout << "Student's Name: ";
std::cin >> name;
}
do
{
flag = 0;
std::cout << "Please input your first exam grade and press enter: \n";
std::cin >> first;
if ((first < 0) || (first > 100))
{
std::cout << "You've entered invalid data!" << '\n';
flag = 1;
}
}while (flag == 1);
do
{
flag = 0;
std::cout << "Please input your second exam grade and press enter: \n";
std::cin >> second;
if ((second < 0) || (second > 100))
{
std::cout << "You've entered invalid data!" << '\n';
flag = 1;
}
}while (flag == 1);
do
{
flag = 0;
std::cout << "Please input your third exam grade and press enter: \n";
std::cin >> third;
if ((third < 0) || (third > 100))
{
std::cout << "You've entered invalid data!" << '\n';
flag = 1;
}
}while (flag == 1);
do
{
flag = 0;
std::cout << "Please input your final exam grade and press enter: \n";
std::cin >> fourth;
if ((fourth < 0) || (fourth > 100))
{
std::cout << "You've entered invalid data!" << '\n';
flag = 1;
}
}while (flag == 1);
//Formulas that calculate student average
grade = (first + second + third + fourth)/4;
sum = first + second + third + fourth;
average = sum/4;
//Letter grade and it's weighted averages
letter = 'A';
letter = 'B';
letter = 'C';
letter = 'D';
letter = 'F';
if(grade >= 90)
{
letter = ('A');
std::cout<<letter<<'\n';
}
else if(grade >= 80)
{
letter = ('B');
std::cout<<letter<<'\n';
}
else if(grade >= 70)
{
letter = ('C');
std::cout<<letter<<'\n';
}
else if(grade >= 60)
{
letter = ('D');
std::cout<<letter<<'\n';
}
else if (grade < 60)
{
letter = ('F');
std::cout<<letter<<'\n';
}
weighted1 = (first * .20);
weighted2 = (second * .20);
weighted3 = (third * .20);
weighted4 = (fourth * .40);
weighted_average = (weighted1 + weighted2 + weighted3 + weighted4);
//Output
std::cout << "Exam Grades: " << first << "," << second << "," << third << "," << fourth << '\n';
std::cout << "This is the average for " << name << ": " << weighted_average << '\n';
std::cout << "This is the letter grade: " << letter << '\n';
}
{
//Writing the grade into grades.txt
for(count =0; count < num; count++)
{
std::ofstream myfile;
myfile.open ("grades.txt");
myfile << "Writing this to a file: ";
myfile << name << ' ';
myfile << weighted_average << ' ';
myfile << letter << '\n';
myfile << "****";
myfile.close();
}
break;
}
//Here we open "grade.txt" to output grade to screen
case 2:
in_stream.open("grade.txt");
out_stream.open("finalgrade.dat");
letter = 'A';
letter = 'B';
letter = 'C';
letter = 'D';
letter = 'F';
if(grade >= 90)
letter = ('A');
else if(grade >= 80)
letter = ('B');
else if(grade >= 70)
letter = ('C');
else if(grade >= 60)
letter = ('D');
else if (grade < 60)
letter = ('F');
weighted1 = (first * .20);
weighted2 = (second * .20);
weighted3 = (third * .20);
weighted4 = (fourth * .40);
weighted_average = (weighted1 + weighted2 + weighted3 + weighted4);
std::cout << "Enter file name: ";
std::cin >> file;
if(file != "grade.txt")
{
std::cout << std::fixed << "The average grade for: " << name << '\n';
std::cout << "average in grade.txt is: "<< weighted_average << std::setprecision(2) << '\n';
std::cout << "and the letter grade is: " << letter << '\n';
}
else
{
return 0;
}
in_stream.close();
out_stream.close();
}
return 0;
}
}
EDIT: The more serious issue here is that you're only storing the last input. You should create an object to store all of the data for each student (e.g. a Student object), create an array of students, and loop through that array to print the information after you have all of your input. I've updated the code below to what it would look like for an array of objects.
If you don't know any object-oriented programming concepts, you could also put each piece of data (name, letter grade, average, etc.) in an array, where the 0th element in each would all represent one student, the 1st would represent another, etc. This isn't good practice; it's a much better idea to create an object to store the information about a student.
Original: You're overwriting your file instead of appending to it by opening and closing it inside every iteration of the loop.
Instead, open your file before the loop and close it after, like this:
{
//Writing the grade into grades.txt
std::ofstream myfile;
myfile.open ("grades.txt");
for(count =0; count < num; count++)
{
myfile << "Writing this to a file: ";
myfile << students[count].name << ' ';
myfile << students[count].weighted_average << ' ';
myfile << students[count].letter << '\n';
myfile << "****";
}
myfile.close();
}
if your trying to output many things i suggest you
Iterate through the loop adding your intended output to a variable, after the loop finishes output that variable
Example
var output
while(true) {
add to output
}
print output