C++ won't add values passed in - c++

When I pass in a value and assign it to another variable, it never seems to add them together. It only outputs both totals in the file, but not together. Can anyone point out my mistake?
void financialReport(int price)
{
ofstream financial_log("financial.txt", ios::app);
int total = 0;
total += price;
int test = total++;
financial_log << "Total: " << test;
financial_log.close();
}
cout << "Destination: ";
cin >> destination;
cout << "Price agreed: ";
cin >> price;
financialReport(price);
This is the output I get in my text file:
Total4Total5
Also, for some reason, there is no space between the total and the price.

It's a little hard to understand your question but I think one issue conuld be confusion about how the ++ operator works. variable_name++ will increment the variable after its evaluation in the current statement and ++variable_name will increment the variable before its evaluation in the current statement.
In your code above, ++ has no effect. If you want your variable test to have a value of one greater than total. Then you need to do this:
int test = ++total;
However, honestly in your case, that doesn't even make sense since total isn't used anywhere in the function after that. You would be better off just simply doing:
int test = total + 1;
Try opening a separate and specific questions about any ios or in/out formatting concerns.
It also looks like you're somehow trying to come up with a total across two function calls using a local variable which will never work because total will get reset to 0 on every function call.
I would be willing to bet that if you do as A. Yurchenko suggests you will probably find your own bug.

If you want to store total value in a file, you may use this:
void financialReport(int price) {
ifstream financial_log_in("financial.txt");
int total = 0;
string dummy;
while (financial_log_in >> dummy && dummy != "Total:") {
}
if (dummy == "Total:") {
financial_log_in >> total;
}
ofstream financial_log_out("financial.txt");
total += price;
financial_log_out << "Total: " << total << endl;
financial_log_out.close();
}
Here we read the current value from financial.txt, update it and write it back.
But in case you just call the function a few times during one runtime this will be more efficient:
void financialReport(int price) {
static int total = 0;
ofstream financial_log("financial.txt");
total += price;
financial_log << "Total: " total << endl;
}
This way financialReport(5); financialReport(6); will result in Total: 11, but when you restart the program total will be 0 again.
Please, notice that both methods will overwrite financial.txt. If you don't want this behavior add ios::app flag to the constructor of the ofstream objects.

Related

What is the difference between "sum = addTwoNumbers" to just calling "addTwoNumbers"?

I'm a freshman in IT and we're currently discussing functions in C++. I just want to ask the difference between our prof's code and the other code that I tried.
This is the sample code our prof showed us:
#include<iostream> //header file
using namespace std;
int num1, num2, sum = 0; // global variable
int addTwoNumbers(int a, int b)
{
sum = a + b;
return sum;
}
int main()
{
cout << "Enter first number: ";
cin >> num1;
cout << "Enter second number: ";
cin >> num2;
sum = addTwoNumbers(num1, num2);
cout << "\nThe sum is " << sum;
}
and as for the code I tried, I simply removed the "sum =" part. So,
addTwoNumbers (num1, num2);
cout << "\nThe sum is " << sum;
and it still did the same thing. At least, from what I saw in the output. Is there any difference between the two behind the scenes or is there really nothing?
The 1st code is ... confusing. I hope your professor didn't show this code to introduce you to functions, but to rather quiz your already knowledge of functions and global variables.
The confusing part are the global variables and how they are used inside the function. If we remove them and forget about them completely the code is better suited to teach you about functions. Let's see:
#include <iostream>
int addTwoNumbers(int a, int b)
{
int sum = a + b;
return sum;
// or simply:
// return a + b;
}
int main()
{
int num1, num2;
std::cout << "Enter first number: ";
std::cin >> num1;
std::cout << "Enter second number: ";
std::cin >> num2;
int sum = addTwoNumbers(num1, num2);
std::cout << "\nThe sum is " << sum;
}
Now there are no hidden dependencies between main and addTwoNumbers (in the form of the global variables). This illustrates the procedure of passing data to function and getting data back from the function (parameters and return). Analyze this code and understand how it works. Play with it.
Now this won't work:
addTwoNumbers (num1, num2);
cout << "\nThe sum is " << sum;
Because the only way data escapes the function is via its return. Since you discard the return value (you don't assign the result of calling the function) you don't have the result of the sum.
Now you could say you could do this instead:
int sum = num1 + num2;
cout << "\nThe sum is " << sum;
and ask "what's the point of functions?"
True for this particular small function there is no practical point of having it. You'll always write the num1 + num2 instead. However its simplicity makes it perfect as a teaching tool. You will soon see functions that get more complex and you will learn (either by being told or learning yourself the hard way) that writing code in very small chinks (functions) is better for both writing (breaking down the big problem in smaller problems) as well as for reading.
First of all, the reason why the sum is returning those values is that you are assigning the sum to itself. Basically, the addTwoNumber() returns the sum, and then you are assigning that value back into the sum. Hence, you don't need to assign the sum again in other words (sum = addTwoNumbers is unnecessary).
Yes, your code is working and it is actually better than the teachers in this case. However, your teacher may want to show you that you can use global variables like this. Typically you would store that value in another variable for later use if needed.

Printing wrong values

I am trying to build a program that outputs No. of people I have entered and the average of their ages. This is my code
#include <iostream>
#include <string>
using namespace std;
int main()
{
int age;
int total = 0;
int No_of_People = 0;
while (age != -1){
total = total + age;
No_of_People++;
cout << "Enter a person's age or enter -1 to stop\n";
cin >> age;
}
cout << "Number of people entered:\n" <<No_of_People<< endl;
cout << "Average age of people = "<< total/No_of_People;
return 0;
}
However the computer prints the average wrong, anyone know what i did wrong?
This is the output
I see two major problems in your code: First, age is not initialized. Reading from it leads to undefined behavior (as mentioned by UnholySheep). Everything could happen from some seemingly random value to an access violation. I once forgot to initialize a boolean variable, it was initialized with false on my computer every time I ran the program (like I intended), on another team members it was initialized to true and we wondered why it's working for me but not for him. So best initialize it with 0 like you do for total.
Second, you're adding age on total before knowing its value. So when you set age to 0 in the beginning, you will increase the number of people one more time than you increase the total age. Add age to total after asking for a value.
A third thing is, that you don't take care for -1 properly. You're increasing the number of people even if -1 is typed in. You should check for that value before increasing the number of people or adding it to your total.
Just thought I would add to Tobias Brösamle's answer.
A good hint that you did not initialize age might be that running the program multiple times with the same input values yields different results.
Have a look at these modifications, comments highlight changed code.
Mostly I see that you're a beginner in coding, your errors can be attributed to not quite developing a "working methodology" - i.e. always initialising variables. I also moved the code into a separate function, whenever I put test code in a main function it very quickly develops into needing to do this anyway.
#include <string>
#include <iostream>
using namespace std;
void age()
{
int age = 0; // not initalised
int total = 0;
int count = -1; // naming convention of previous variable didn't match other variables
do // loop terminates at bottom
{
cout << "Enter a person's age or enter 0 to stop\n"; // why \n here instead of endl?
cin >> age;
total += age;
count++;
} while (age > 0); // slightly easier code to write if 0 terminates instead of -1
cout << "Number of people entered:\n" << count << endl;
cout << "Average age of people = " << total / (float)count; // floating point result
}
int main()
{
age();
char temp;
cin >> temp;
}
you should copy the code
cout << "Enter a person's age or enter -1 to stop\n";
cin >> age;
before the while loop.

Why isn't the variables arithmetic working?

Here is code:
#include<iostream>
#include<string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
int score_one;
int score_two;
int score_third;
int final_score = score_one * score_two * score_third;
int main()
{
cout << "What was your first score?" << endl;
cin >> score_one;
cout << "What was your second score?" << endl;
cin >> score_two;
cout << "What was your third score?" << endl;
cin >> score_third;
cout << "Your average score is: " << final_score << endl;
return 0;
}
Originally I am trying to get the average, by dividing the three scores, but that doesn't work, nor my arithmetic. It does not even multiple the variables. I use cin to get the numbers. Not sure what I am missing.
At the time that you assign to final_score, the values of the other scores are 0 (as you haven't assigned to them yet and they're global). You then read into the scores, but never update final_score!
You need to add this after you read in the third score:
final_score = score_one * score_two * score_third;
This will update final_score.
I would also suggest staying away from global variables. I'd also suggest initializing your variables when you declare them to avoid garbage values.
Also, you're not actually calculating the average! To do that, you'll need to add your values and divide by 3, since you have 3 values total. But you've declared final_score as an integer, so you won't be able to store the average with full precision. I'd suggest declaring as a double.
Taking into account all these changes, your code will look like:
int main()
{
int score_one = 0;
int score_two = 0;
int score_third = 0;
double final_score = 0;
cout << "What was your first score?" << endl;
cin >> score_one;
cout << "What was your second score?" << endl;
cin >> score_two;
cout << "What was your third score?" << endl;
cin >> score_third;
final_score = (score_one + score_two + score_third) / static_cast<double>(3);
cout << "Your average score is: " << final_score << endl;
return 0;
}
This line should be moved after you cin to the variables on the right hand side of the equation
int final_score = score_one * score_two * score_third;
cout << "Your average score is: " << final_score << endl;
The variable isn't somehow recomputed when those variables are later set.
This part
int final_score = score_one * score_two * score_third;
should be inside main() after the last cin.
You have already received some answers, but I would like to offer another point of view.
It seems to me that you are used to a program like Excel, where you can set a cell to a formula (like the product of 3 other cells), and then, whenever you change any of those cells, the product is immediately updated, automatically. C++ (and, in general, programming languages) does not work like that. When you write a line like
int final_score = score_one * score_two * score_third;
you are not setting a rule, which will cause the value to be recalculated. The approach is different!
A program is executed from the beginning to the end (in practice, from the top to the bottom), and every time you assign a value to a variable (like final_score), what you are doing is reading the current value of the input variables (here, your three scores), calculating the result (which in this case is undefined, because you haven't initialised any of the scores), and assigning it to the variable, just this time. That's it. If you later change the scores, the change will not be reflected automatically on your final_score. If you want the value to be recalculated, you have to do it manually. That's why you have to move that line after the lines that read the input from the user, as the others have said.
You really should not use global variables, see here on why you should avoid them.
Next, instead of doing using std::cin etc. Just get used to typing it.
Lastly, use appropriate flags in your compiler to help you catch mistakes. The compiler is meant to be your friend. A good compiler would tell you,
int score_one;
int score_two;
int score_third;
int final_score = score_one + score_two + score+third / 3;
Is not initialized. To really achieve what you are thinking, you could use a function that will return a double. And that would look something like
double doAverage(int score1, int score2, int score3)
{
return (score1 + score2 + score3) / 3.0;
}
But that will probably come later in your coding practices.
#include<iostream>
int main()
{
// Delare your variables here and initialize them to zero.
int score_one = 0;
int score_two = 0;
int score_third = 0;
double final_score = 0;
std::cout << "What was your first score?" << std::endl;
std::cin >> score_one;
std::cout << "What was your second score?" << std::endl;
std::cin >> score_two;
std::cout << "What was your third score?" << std::endl;
std::cin >> score_third;
// Take all scores and divide it. This is the important part since
// order matters in your code.
final_score = (score_one + score_two + score_third) / 3.0;
std::cout << "Your average score is: " << final_score << std::endl;
return 0;
}
You're on the right track, you just have to look at your code and read it outloud to yourself. One of the best things you can do in programming is starting from the top and saying, "Okay, where does this break?" And follow it line by line making sense of it.

Transversing an Array of structs error in C++

Current code:
const int MAX_CODENAME = 25;
const int MAX_SPOTS = 5;
struct Team {
string TeamName[MAX_CODENAME];
short int totalLeagueGames;
short int leagueWins;
short int leagueLoses;
};
//GLOBAL VARIABLES:
Team league[MAX_SPOTS];
void addTeams(){
int i = 0; //first loop
int j; //second loop
while(i < MAX_SPOTS){
cout << "****** ADD TEAMS ******" << endl;
cout << "Enter the teams name " << endl;
scanf("%s", league[i].TeamName) ;
}
void searchTeam(){
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
for(int i = 0; i < MAX_SPOTS; i++){
if(decider == league[i].TeamName){
cout << endl;
cout << league[i].TeamName << endl;
break;
}else{
cout << "Searching...." << endl;
}
}
}
I really dont know why its not working but I have included all the perquisite header files such as and but the program crashes when i enter the data and then attempt to search. I get the circle of death and then program not responding then says Process returned 255 (0xFF) . It does not even out put Searching.... the program practically gives up as soon as I enter that name.
Also if this can be optimized by the use of pointers that would be great.
tl;dr run-time error causing the search to fail as soon as i type in a name. And for the record I have checked to make sure the name I entered is valid.
scanf doesn't know about std::string. Use std::cin >> league[i].TeamName.
scanf("%s", league[i].TeamName) ;
This should be changed to
std::cin >> league[i].TeamName ;
A couple of other things here....
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
Every time you input a value, you are telling the computer to hold the inputted value at decider[25] but the computer only reads indexes 0-24.
if(decider == league[i].TeamName){
Which array slot are you comparing the team name to? If its the 25th element than the statement should be
if(decider[24] == league[i].TeamName){
Pointers are better suited if the number of TeamNames are unknown. Based on the limited code presented, I highly recommend you stay within the realm of basic data types. For the purposes of troubleshooting, please post your full code in the future.
Your TeamName member variable:
string TeamName[MAX_CODENAME];
is an array of 25 strings, so in this line:
scanf("%s", league[i].TeamName) ;
you are courrupting the array. You don't really want an array anyways, so change the TeamName declaration to:
string TeamName;
and then when you read the name, you'll need to use iostreams which knows how to populate a string type (scanf only works with c char arrays):
std::cin >> league[i].TeamName

My search function in C++ is pulling up all the answers and not a single one

I'm really confused. I have to make this lab for a class and I can't seem to have the search only display one result but all of the months of the year. I also can't seem to figure out why its not displaying the TotalRainfall when I input 0 into the month of the year.
Thank you.
#include <iostream>
#include <fstream>
const int MaxSize = 12; //How many weather lines will be available.
using namespace std;
struct WeatherInformation
{
int Month; //Months of the year
float TotalMonthsRainfall; //Total amount of rainfall
float HighTemp; //The Highest temperature of the month.
float LowTemp; //The Lowest temperature of the month.
float AverageTemp; //The Average temperature of the month.
};
WeatherInformation WeatherArray[MaxSize]; //Declaring a month array of MaxSize
void ReadFile(ifstream& MyinFile, WeatherInformation WeatherArray[]);
void WeatherMonthSearch (WeatherInformation WeatherArray[]);
int main()
{
float TotalRainfall = 0;
int count = 1; //Counts how many times the for loop goes.
int MonthOfWeather; //User input of the month.
char ProgramRedo; //User input if they want to reuse the program.
char exit_char; //User input to exit the program.
ifstream MyinFile; //Variable that uses file.
ReadFile (MyinFile, WeatherArray); //Call ReadFile Function
WeatherMonthSearch (WeatherArray); //Call WeatherMonthSearch Function
MyinFile.close(); //Closes file.
}
//Brett Holmes
//4/30/2013
//PreCondition:You need a file labeled weather.dat
//PostCondition: It puts the file variables into an array.
void ReadFile(ifstream& MyinFile, WeatherInformation WeatherArray[])
{
float TotalRainfall = 0;
char exit_char;
int count = 0;
int Month = 0;
cout << "Your Weather Machine" << endl << endl;
MyinFile.open("weather.dat");
if (!MyinFile)
{ //no
cout << "Can't open input file." << endl; //Tests the right file.
char exit_char; //End Program
cout << "Press any key to exit" << endl;
cin >> exit_char;
}
for(count = 1; count < MaxSize; count++) //Puts the file variables in the array.
{
WeatherArray[count].Month = WeatherArray[count].Month + 1;
MyinFile >> WeatherArray[count].TotalMonthsRainfall;
MyinFile >> WeatherArray[count].HighTemp;
MyinFile >> WeatherArray[count].LowTemp;
(WeatherArray[count].AverageTemp = ((WeatherArray[count].HighTemp + WeatherArray[count].LowTemp)/2));
(TotalRainfall = TotalRainfall + WeatherArray[count].TotalMonthsRainfall);
}
}
//Brett Holmes
//4/30/13
//PreCondition:You need to have the months already put into an array in a struct.
//PostCondition:Outputs the rainfall stats the user puts in then asks to run again.
//Outputs a error message if they type in the month wrong.
void WeatherMonthSearch (WeatherInformation WeatherArray[])
{
float TotalRainfall;
int months;
int MonthOfWeather;
char ProgramRedo;
do
{
bool MonthFound = false;
cout << "Please input the number of the Month. Ex. 1=Jan. 2=Feb. etc \n\n";
cin >> MonthOfWeather;
for(int i = 1; i <= MaxSize; i++)
{
months = WeatherArray[i].Month;
if(months == MonthOfWeather ) //Finds the artist and outputs the results
{
cout << "\nTotal Months Rainfall: " << WeatherArray[i].TotalMonthsRainfall << " \n";
cout << "Highest Temperature: " << WeatherArray[i].HighTemp << " \n";
cout << "Lowest Temperature: " << WeatherArray[i].LowTemp << " \n";
cout << "Average Temperature: " << WeatherArray[i].AverageTemp << " \n";
MonthOfWeather = true;
}
}
if(MonthOfWeather == 0)
{
cout << "The total rainfall for the year is: " << TotalRainfall << ".";
}
if(MonthFound == false)
{
cout << "\nMonth Number error. Month not found. Try again.\n\n";
MonthOfWeather = false;
}
cout << "Would you like to look up another month of weather?\n";
cout << "Enter a 'Y' if yes and 'N' if no.\n";
cin >> ProgramRedo;
}while(ProgramRedo == 'Y');
}
Several obvious problems:
Arrays in C++ is 0-based, so your for loop is off-by-one. In your search function, for(int i = 1; i <= MaxSize; i++) should be for(int i = 0; i < MaxSize; i++). Similarly, in your read function, for(count = 1; count < MaxSize; count++) should be for(count = 0; count < MaxSize; count++) (If you want to skip index 0 because you are using it as a signal value, then you should set MaxSize to 13 and have the loop start at 1.)
Why are you assigning a boolean to MonthOfWeather? Do you mean MonthFound?
You read function is not setting the months correctly. WeatherArray[count].Month = WeatherArray[count].Month + 1; should be WeatherArray[count].Month = count; if you are using a 1-based loop or WeatherArray[count].Month = count + 1; if the loop is 0-based.
You calculated your total rainfall in the read function, but the result is stored in a local variable so it's lost when the read is done. Either make TotalRainfall a global variable or do your calculations in your search function.
There are a lot of redundant variable definitions: for example, your weather data array is a global so there is no reason to actually pass it around; exit_char is declared twice in your read function; the first five lines of your main() declared variables that you never used.
Also, your read function does not actually exit the program on failure - it even still attempts to read from the stream and then call your search function! If error-checking is a requirement, you should either have the read function return a boolean and check that the read function succeeded before calling your search function, or simply call std::exit after that cin >> exit_char;.
So, one problem you have is that you have local variables that appear in multiple places, but appears like you expect them to actually contain the same information.
For example, I see three different TotalRainFall. One in main, which is just there, not used for anything, one in ReadFile which is calculated, and one in WeatherMonthSearch, which is not set to anything.
I suspect you want all three of these to actually do something. One way to achieve that would be to remove the local ones in ReadFile and WeatherMonthSearch, and instead pass in the one from main (as a reference into ReadFile).
There's also a few places where you use variables without initializing them. Make it a habit to initialize EVERYTHING and EVERYWHERE!
Enable warnings in your compiler - if you have any form or reasonably new compiler (gcc or MS Visual Studio of recent vintage), it should tell you at least some of these things.