I am fairly new to this site, and programming in not my strong suit, so I apologize if the way I word things are hard to follow. Below is a code I have written to calculate the odds of profiting from playing lottery scratchers. It is suppose to output the results to a .txt file. I am able to get it to output to that file, and the everything in the output file is correct, except for the name of the second game. It is missing a whole word. How my output file looks is shown below.
Game Cost Odds
-----------------------------------------------
SMALL BEANS $ 1 1 in 1.67
BOOTY, ARRR $ 10 Not possible
MONEY HU$TLA$ $ 20 1 in 99.80
The second and third games both have a space before they start, and I am not sure why. Also, the second game is suppose to say "Pirate's Booty, Arrr." I do not understand how a whole word is missing. Any help on how to fix this would be very much appreciated. My code is below.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
int main()
{
// Declaring Variables
int Profit; // The lowest dollar amount you want to profit
int CostOfTicket; // The cost of the ticket in the dollar amount
int NumberOfPrizes; // The number of possible prizes that can be won
int PrizeValue; // The value of the prize in dollars
int NumberOfTickets; // The total number of tickets that were printed with that prize
int TicketsNotClaimed; // The number of tickets with that prize that have not yet been claimed
double RemainingTickets; // Total number of tickets that are remaining
double RemainingTicketsForProfit; // The total number of tickets for a profit that are remaining
double Odds; // The odds of winning the game
string game; // The name of each game that can be played
string output; // The name of output file the user chooses (.txt)
// Open the input text file
ifstream inputfile ("scratcher.txt"); // Open the input file called "scratcher.txt"
// The program will ask the user to enter the lowest amount they would like to profit by when playing one of the lottery games.
// The games include "Small Beans," "Pirate's Booty, Arrr," and "Big Money Hu$tla$."
cout << "Enter the lowest dollar amount that you would like to profit: ";
cin >> Profit;
cout << "Enter the output file name: ";
cin >> output; //name of output file user chooses
ofstream outputfile (output.c_str()); //creates an output file with the name user chose for output
cout << "Generating report...";
// How the output will be formatted
outputfile << left << setw(25) << "Game" << setw(10) << "Cost" << setw (10) << "Odds" << endl;
outputfile << "-----------------------------------------------" << endl;
// Reads the name of the game
while (getline(inputfile, game))
{
inputfile >> CostOfTicket; // Reads the cost of the ticket
inputfile >> NumberOfPrizes; // Reads the number of prizes
RemainingTickets = 0;
RemainingTicketsForProfit = 0;
for (int i = 0; i < NumberOfPrizes; i++)
{
inputfile >> PrizeValue; // Reads the value of the prize
inputfile >> NumberOfTickets; // Reads the total number of tickets
inputfile >> TicketsNotClaimed; // Reads the number of tickets that are not claimed
RemainingTicketsForProfit = RemainingTicketsForProfit + TicketsNotClaimed;
// The next line will compute a sum of the number of the remaining tickets where the user would profit
if (PrizeValue > Profit)
{
// The following line computes the running sum of the number of tickets remaining for that game.
RemainingTickets = RemainingTickets + TicketsNotClaimed;
}
}
// Tells the program what to do if there are no tickets remaining
if (RemainingTickets == 0)
{
// Formats the output
outputfile << left << setw(25) << game << setw (2) << "$" << CostOfTicket << right << setw(15) << "Not possible" << endl;
}
else
{
// Tells the program to calculate the odds.
Odds = RemainingTicketsForProfit / RemainingTickets;
outputfile << left << setw(25) << game << setw (2) << "$" << CostOfTicket << right << setw(15) << "1 in " << setprecision(2) << fixed << Odds << endl;
}
string blankLine;
inputfile >> blankLine;
}
// Closes the input and output text file
inputfile.close();
outputfile.close();
return 0;
}
string blankLine;
inputfile >> blankLine;
Not sure why you did this but it's eating up the first word of your next line.
Remember, operator>> into a string skips whitespace then eats precisely one word.
Whatever you're trying to do regarding skipping blank lines, this is not how to do it!
Related
Disclaimer: I am a beginner to programming, so what I say might sound really stupid
I have to make a "Telephone Directory" for school. The program isn't complete, but there are some things that I need to fix before moving on. The array TelephoneNumbers either isn't storing the numbers from the file correctly, or isn't displaying them. For the SeaerchRecords function, the first number in the file is displayed correctly, the second is displayed as "2147483647," and the rest of the numbers display as "0." The modify function also doesn't change the number, and I confirmed this with the while in the function. The string array works perfectly fine, however. May someone explain what I'm doing incorrectly?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string TelephoneNames[100];
int TelephoneNumbers[100];
void ModifyRecords(); //Function to Modify Records
void SearchRecords(); //Function to Search Records
void DeleteRecords(); //Function to Delete Records
int main()
{
fstream inputFile;
fstream outputFile;
char choice;
inputFile.open("Telephone Names.txt"); //To store
for (int count=0;count<100;count++) //file names
{ //into a
inputFile >> TelephoneNames[count]; //string
}
inputFile.close();
inputFile.open("Telephone Numbers.txt");//To store
for (int count=0;count<100;count++) //file #'s
{ //into a
inputFile >> TelephoneNumbers[count];//string
}
inputFile.close();
//Display options available
cout << " Hello, do you want to:\n";
cout << " ======================\n";
cout << "-Modify Records|Enter M\n";
cout << "-Search Records|Enter S\n";
cout << "-Delete Records|Enter D\n";
//Store choice
cin >> choice;
//Send to different function
if (choice=='M'||choice=='m')
{
ModifyRecords();
}
if (choice=='S'||choice=='s')
{
SearchRecords();
}
return 0;
}
void ModifyRecords()
{
string name;
string newname;
int newnumber;
int count=0;
cout << "Enter the name of the person: ";
cin >> name;
for (count=0;TelephoneNames[count]!=name;count++)//To determine where in the strings the new numbers need to be
{
}
cout << "Enter the new name of the person: ";
cin >> newname;
cout << "Enter the new number of the person: ";
cin >> newnumber;
TelephoneNames[count]={newname};
TelephoneNumbers[count]={newnumber};
count=0;
while (count<6)
{
cout << TelephoneNames[count] << endl;
cout << TelephoneNumbers[count] << endl;
cout << endl;
count++;
}
}
void SearchRecords()
{
string name;
int count=0;
cout << "Enter the name of the person you would like to find: ";
cin >> name;
for (count=0;TelephoneNames[count]!=name;count++)//To determine where in the strings the new numbers need to be
{
}
cout << "Name: " << TelephoneNames[count] << endl;
cout << "Number: " << TelephoneNumbers[count] << endl;
}
Since there is no any answer still and I don't see exactly the problem at this point I'll provide some suggestions how you can find a problem in your code.
In any programming situation when you can't find a bug, first task is to locate it as much precisely as you can and check all input data and assumptions. Usually, debugger is used for such purposes, but you can just output text in console before creating final version of your program.
To start with, you must check that you really received names and telephones from your file:
inputFile.open("Telephone Names.txt"); //To store
for (int count=0;count<100;count++) //file names
{ //into a
inputFile >> TelephoneNames[count]; //string
cout << TelephoneNames[count] << endl; //WE MUST SEE WHAT IS REALLY STORED IN TelephoneNames
}
inputFile.close();
inputFile.open("Telephone Numbers.txt");//To store
for (int count=0;count<100;count++) //file #'s
{ //into a
inputFile >> TelephoneNumbers[count];//string
cout << TelephoneNumbers[count] << endl; //WE MUST SEE WHAT IS REALLY STORED IN TelephoneNumbers
}
inputFile.close();
Ok, when it is checked and you are defenitely sure there is no problem in your data we can move to SeaerchRecords function doing the same procedure. We must check what is happening while you are searching:
for (count=0;TelephoneNames[count]!=name;count++)//To determine where in the strings the new numbers need to be
{
cout << "Search step: " << count << " name " << name << " found name " << TelephoneNames[count] << " number " << TelephoneNumbers[count] << endl;
}
Doing so you will locate your bug rather quickly. The problem can be in input files format, in difference of "name" and stored names format etc.
I'll provide several additional suggestion how you can improve your code.
1) Try to use const declarations for such commonly used things as number of records (const int NUMBER_OF_RECORDS = 100; insted of just putting '100' everywhere), it will reduce the amout of work and possible bugs. 2) Try to check all possible problems that you program can encounter if someting is wrong with data. What will happen if you have less than 100 records in your files now? Program crush or silent reading of unappropriate data which is even worse. Check that you haven't reach file end on any step of reading along with current check that you've reached you number of records and do something in case of unappropriate data.
3) Check the possible problems with conditions in your cycles not to run them infinite number of times. Now your condition for(count=0;TelephoneNames[count]!=name;count++)
will execute forever if there is no such name or just crush the program on count 100 or more. You should check that count doesn't exceed that value. Good luck!
I have a question about using fin and loops correctly in C++. I have a file I read from that has 78 lines of data consisting of a ski resort name, its elevation, and then 12 numbers that are the monthly precipitation. The program is supposed to read from that file then output to a different file the name, elevation, and the average annual precipitation. For some reason I can't get the average to work right. I have to have one loop run for each of the 78 lines, then a nested loop run to process each of the 12 months.
I also have to use a cin.ignore that I don't know where to put.
Code:
int main() {
ifstream fin("../Debug/monthlyPrecipitation.txt");
if (fin.fail())
{
cout << "Error opening file." << endl;
}
ofstream fout;
fout.open("../Debug/annualPrecipitation.txt", ios::app);
int elevation;
const int MONTHSPERYEAR = 12;
double average, precipTotal, precip;
string stationName;
fout << "Annual Precipitation Report" << endl;
fout << endl;
fout << "Weather Station" << setw(18) << "Elevation" << setw(12) << "Precipitation" << endl << endl;
for (int counter = 1; counter <= 78; ++counter)
{
getline(fin, stationName, '\t');
fin >> elevation;
for (int counter = 1; counter <= 12; ++counter)
{
fin >> precip;
precipTotal = precipTotal + precip; //the issue is here
}
average = precipTotal / MONTHSPERYEAR;
fout << stationName << setw(22) << elevation << setw(12) << average << endl;
}
Thanks.
Along with contaminating precipTotal, It looks like you're forgetting to turn the line into a stringstream. I'm assuming that a line in your file looks like:
Resort_Name elevation precip1 precip2 ... precip12
if you get that line, then you're grabbing all the precips along with it, and then when you fin in the inner loop, you're reading in the next line. What you need to do is get that line, and turn it into a stringstream. Then, read in the resort name into a different string, the elevation into an int, and then calculate the average without contaminating the total.
You're not clearing precipTotal before the inner loop, thus contaminating the average of a given station with the results of the previous ones.
You don't initialize all the POD variables such as elevation, average, precipTotal, and precip.
However, only precipTotal has an issue because the others have new value in the loop.
I am creating a school project but seems lost at the moment. Can someone help me figure out my problem? Here's what's going on:
I have a program that outputs a random generated numbers in a text file using ofstream. It is generated with a format of two columns (one column is SalePrice & the second column RegularPrice). My problem is creating a code that will do the following:
Create a function that will read the text file generated by the first program
Find the average of the second column ONLY! (Regular Price) then outputs it in the screen
Find the minimum and maximum of the second column ONLY! (Regular Price) then outputs it in the screen
Please help! I need help how to code the ifstream part, I am new to C++ and have tried all the solutions in many books but doesn't seem to work for my needs? :-( Any help will be greatly appreciated! Thanks in advance!
Here's just the section of my code (not the entirety), it is not giving me an error . . . it is simply not giving me anything:
float SalePrice[userInput];
float RegularPrice;
string cPrice;
string readFile;
int count = 0;
ifstream inputFile;
inputFile.open(fileName);
inputFile >> RegularPrice;
// To get you all the lines and place the line from myfile into the line variable
while(!inputFile.eof() && getline(inputFile, readFile))
{
if (count < userInput)
{
inputFile >> readFile;
readFile += cPrice; // Saves the line in STRING.
//display the line we gathered:
cout << cPrice << endl;
}
++count;
}
avgRPrice = RegularPrice / userInput;
cout << endl;
cout << fixed << setprecision (2);
cout << "The average of all the Regular Prices in the file is: " << avgRPrice << endl;
cout << "The minimum Regular Price in the file is: " << minRPrice << endl;
cout << "The maximum Regular Price in the file is: " << maxRPrice << endl;
EDITED:
Here's my current code for finding the max & min:
int maxRPrice(float RPrice[])
{
if (RPrice > maxRPrice)
maxRPrice = RPrice;
return maxRPrice;
}
int minRPrice(float RPrice[])
{
if (RPrice < minRPrice)
minRPrice = RPrice;
return minRPrice;
}
Here is an improved version of your code which works perfectly for me:
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
const int userInput = 2;
float SalePrice[userInput]; //Make an array
float RegularPrice[userInput]; //Make an array
string readFile;
ifstream inputFile;
inputFile.open("yourFile.txt");
if(!inputFile){ //Check wether the file is open
cout<<"Couldn't open file!" << endl;
return -1;
}
// To get you all the lines and place the line from myfile into the line variable
for(int count = 0; !inputFile.eof() && (count < userInput) ; ++count) //Why are you using a while-loop if you need to count the iterations
{
//
inputFile >> SalePrice[count] >> RegularPrice[count]; //loads column SalePrice/RegularPrice into the array at position 'count'
}
float sumRegularPrice = 0;
for(int i=0; i < userInput; i++)
sumRegularPrice += RegularPrice[i];
float avgRPrice = sumRegularPrice / userInput;
cout << endl;
cout << fixed;
cout << "The average of all the Regular Prices in the file is: " << avgRPrice << endl;
//cout << "The minimum Regular Price in the file is: " << minRPrice << endl;
//cout << "The maximum Regular Price in the file is: " << maxRPrice << endl;
system("pause");
return 0;
}
Why are you loading RegularPrice only once? As far as I got your explanation about the file format (you said one column is SalePrice & the second column RegularPrice), every line might have this content:
3.44 5.99
To get the min and max price you can simply write two functions.
With this input:
3.44 5.99
5.54 8.99
I get this output (in the console):
The average of all the Regular Prices in the file is: 7.490000
If you have some questions don't hesitate to ask me.
I am completing a lab assignment where the user is prompted for the type if fish they wish to order and to enter the price per pound. The user needs to be prompted for the type of fish and the price two times before the report prints.
The problem is that the program ends before the first instance of the loop has completed. (The way the code is written the titles on the report will print twice, but that was in the instructions.)
The code is below and any assistance is greatly appreciated.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
float price;
string fishType;
int counter = 0;
// Change the console's background color.
system ("color F0");
while (counter < 3){
// Collect input from the user.
cout << "Enter the type of seafood: ";
cin >> fishType; // <------ FAILS AT THIS POINT. I GET THE PROMPT AND AT THE "ENTER" IT DISPLAYS THE REPORT
cout << "Enter the price per pound using dollars and cents: ";
cin >> price;
counter++;
}
// Display the report.
cout << " SEAFOOD REPORT\n\n";
cout << "TYPE OF PRICE PER" << endl;
cout << "SEAFOOD POUND" << endl;
cout << "-------------------------------" << endl;
cout << fixed << setprecision(2) << showpoint<< left << setw(25)
<< fishType << "$" << setw(5) << right << price << endl;
cout << "\n\n";
system ("pause");
return 0;
}
The new line character will not have been consumed by the read, using std::istream::operator>>(float), of the price:
cin >> price; // this will not consume the new line character.
The presence of the new line character during the next read, using operator>>(std::istream, std::string)), into fishType:
cin >> fishType; // Reads a blank line, effectively.
and then the user input that was intended to be the next fishType will be read (and fail to be) by the price as it will not be a valid float value.
To correct, ignore() until the next new line character after the read of the price. Something like:
cin.ignore(1024, '\n');
// or: cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Always check the status of input operation to determine if they were successful or not. This is easily achieved:
if (cin >> price)
{
// success.
}
If the fishType can contain spaces then using operator>>(std::istream, std::string) is not appropriate as it will stop reading at the first whitespace. Use std::getline() instead:
if (std::getline(cin, fishType))
{
}
When the user enters input a new line character will be written to stdin, i.e cin:
cod\n
1.9\n
salmon\n
2.7\n
On first iteration of the loop:
cin >> fishType; // fishType == "cod" as operator>> std::string
// will read until first whitespace.
and cin now contains:
\n
1.9\n
salmon\n
2.7\n
then:
cin >> price; // This skips leading whitespace and price = 1.9
and cin now contains:
\n
salmon\n
2.7\n
then:
cin >> fishType; // Reads upto the first whitespace
// i.e reads nothin and cin is unchanged.
cin >> price; // skips the whitespace and fails because
// "salmon" is not a valid float.
The program I code below should
List all payment made by each student, show amount paid and outstanding
I need some help with the following section:
void payment()
{
// Display message asking for the user input
std::cout << "List all payment made by each student, show amount paid and outstanding." << std::endl;
// Read from text file and Display list of payment
std::ifstream infile; // enable to open, read in and close a text file
float StudentCode; // to store the student enrolment number
float Amount; // to store the amount of money
float Type; // to store information on type of payment made
float Outstanding; // to store amount of money is due
infile.open("Payment.txt"); // open a text file called Payment
if (!infile)
{
std::cout << "Item list is empty" << std::endl; // if the file is empty it output the message
}
else
{
std::cout << "List of Payment: " << std::endl;
std::cout << "" << std::endl;
std::cout << "Enrolment No." << "Amount" << "Outstanding" << std::endl;
// If there is Student Code that has the same number, it need to combined the amount it paid
// For an example
// Student Code: 12 Amount: 25
// Student Code: 12 Amount: 50
// so it should display the following when the program runs:
// Student Code: 12 Amount: 75
while(!infile.eof()) // output the description of the text file onto the screen
{
getline(infile,StudentCode,Amount);
Outstanding = Amount - 100;
std::cout << StudentCode << Amount << "$" << Outstanding << std::endl;
//iter++;
}
std::cout << "End of list\n" << std::endl;
}
infile.close(); // close the text file
}
What is wrong with the getline part:
getline(infile,StudentCode, Amount);
Also the program should not display repeated Student Code but combine the amount it paid.
Where I explain in the comment section
// If there is Student Code that has the same number .....
How do I do this?
getline reads a line from a stream into a string. What you're trying to do, is more like this
while (infile >> StudentCode >> Amount) {
// process values
}
If you want to sum up all amounts, you must first accumulate and afterwards loop through the collected values and print them
std::map<int, float> amountsPaid;
int studentCode;
float amount;
// accumulate amounts
while (infile >> studentCode >> amount) {
amountsPaid[studentCode] += amount;
}
// loop through map and print all entries
for (auto i = amountsPaid.begin(); i != amountsPaid.end(); ++i) {
float outstanding = i->second - 100;
std::cout << i->first << ": " << i->second << "$, " << outstanding << '\n';
}
There are several problems here. One is that getline reads one line of text into a single std::string variable, not multiple float fields.
For that you might try
infile >> StudentCode >> Amount;
A second problem is that
while(!infile.eof())
will not check if the next input is going to work but if the previous input attempt failed beause it reached end-of-file.
The standard method is to combine these into
while (infile >> StudentCode >> Amount)
{
// do something with the code and amount
}
Your call to getline doesn't seem correct.
The documentation states
istream& getline ( istream& is, string& str, char delim );
But your giving it
getline(istream&, float, float);
You should be trying to read the line as a string and then parse out the 2 floats.
Since your using c++, if the file is well formatted you could just redirect cin and it'll be easier. You could just do something like
while (infile >> StudentCode) {
infile >> Amount;
}