Nested If dilemma - c++

I am having troubles understanding this issue. The code is really basic but it behaves rather unexpectedly. The code is the simplified version of a routine to extract and save to a separate file the data for the day 15 of each month out of a daily database. Where is the problem ? The first cout prints the number of any day the outer if is entered. Then there are some conditional lines to select the right day ( not really important in this example ) and then there is the block, the inner if, that should print the data for the day 15 to the new file. Now, as you can see, while the outer loop ( attention ! ) is entered only on the 10th ( and this is already wrong - it should have written all the numbers from 11 to 15 ) but then it also prints that the file is written on the 15 ! Where is the problem ? The OUTER IF was entered only on the 10th, how can be the INNER IF be execute on the 15th ????
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string newdata="mamma";
string risultato="-";
string PriorLine="-";
int PriorDay=0;
int lastmonth=0;
// Loops through all the months
for (int mese=1; mese <=12; mese++)
{
//Loops through all the days in the month
for(int day=1; day<=30; day++)
{
// at the month's beginning these 2 strings are set ="-"
if (mese != lastmonth)
{
risultato="-";
PriorLine="-";
}
// if we are between the 10th and the 20th and the result is still to be found
if (day>=10 && day<=20 && risultato=="-")
{
cout << day << endl; // LISTS ALL THE DAYS THIS LOOP IS ENTERED
if (day=15) // if it is exactly day 15 print that day's result
risultato=newdata;
// if that month in the data there is no day 15 and
// this is the second pass, choose the closest !
if (day>15 && PriorLine !="-")
{
if (abs(day-15)<=abs(15-PriorDay))
risultato=newdata;
else
risultato=PriorLine;
}
PriorLine=newdata;
PriorDay=day;
if (risultato != "-")
{
// writes the result ( risultato ) in a file
cout << "file written on the " << day << endl;
}
}
lastmonth=mese;
}
}
system("pause");
return 0;
}

if (day=15) assigns 15 to day and returns true. You need if (day==15)

When I simply compiled your code with g++ -Wall I got a warning:
error: suggest parentheses around assignment used as truth value
On this line:
if (day=15) // if it is exactly day 15 print that day's result
I'm willing to be the compiler has told you what your problem is. I suggest you enable all warnings in your build system.

Related

I'm unsure exactly why the 'counter' variable isn't responding in the way I would like it to

Please bear with me since I am very new to C++ and coding in general.To the point where this is my second or third time using arrays. Here is the code in question:
#include <iostream>
using namespace std;
int main()
{
int day,month,counter;
int year[12]={31,28,31,30,31,30,31,31,30,31,30,31};
cout<<"Input a day of a month";
cin>>day;
cout<<"Input the month of the year";
cin>>month;
for(int x=0;x>12;x++)
{
cin>>year[x];
counter+=year[x];
}
cout<<"The Date is " <<day<<" / "<<month<<" and, "<<endl;
cout<<"The number of days until this date is reached again is:"<<counter<<endl;
}
I am trying to have the code show an imputed date by the user and the number of days until that date is reached again. However the counter variable is only showing 0. I am decently sure this is some form of logic error I have yet to find.
Your loop
for(int x=0;x>12;x++)
sets x to 0 and then checks if it's greater than 12, which it isn't, and thus ends doing nothing.

Getting "Statement missing ; in function main()" even though I have the semicolon already in C++

Here's the code assignment.
A bank charges $10 per month plus the following check fees for a commercial checking account:
$0.10 each for fewer than 20 checks
$0.08 each for 20-39 checks
$0.06 each for 40-59 checks
$0.04 each for 60 or more checks
The bank also charges an extra $15.00 if the balance of the account falls below $400 (before any check fees are applied). Write a program named lab2 that inputs for the beginning balance and the number of check written from the transaction file. Compute and display the bank's service fees for the month.
Input Validation: Do not accept a negative value for the number of checks written. If a negative value is given for the beginning balance, display an urgent message indicating the account is overdrawn.
The program should have a loop execution of six times for reading data from a file named transaction.txt.
Click the link transaction.txt download the file and store it in folder c:\cis180\lab2. The file transaction.txt contains the beginning balance and number of checks written for six transactions.
Here is the content of the file.
The text file
-100.00 -beginningbalance
30 - number of checks
400.00
-20
300.00
36
300.00
47
350.00
5
300.00
70
My code
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <sstream>
//include a library file to input data from file
using namespace std;
bool isNumeric(string pszInput);
int main()
{//start
// Constants
int numChecks; // Number of checks written for the month
double acctBalance; // Account balance before subtracting check fees
double checkFee; // Fee based on number of checks written
double totalFees; // Total monthly bank fees
ifstream inputFile;
//Open the file
inputFile.open("c:\\cis180\\transaction.txt");
//Initialize month counter
int transaction = 0; //first month
//Create a loop to execute 6 times. Each time the loop body reads the beginning balance and number of checks for six transaction, calculate the bank fees, display the beginning balance, number of checks, and the bank fees.
inputFile >> acctBalance;
// Display the beginning balance
if (acctBalance>0)
{
cout<<"Your beginning balance is: "acctBalance << endl;
}
else (acctBalance<0)
{
cout<<"Your account is overdrawn!" << endl;
}
// Display the number of checks that were written.
if (numChecks>0)
{
cout<<"The number of checks written were: "numChecks<<endl;
}
else (numChecks<0)
{
cout<<"Number of checks must be 0 or more."<<endl;
}
// Determine whether the account is overdrawn.
// Validate number of checks written.
// If the number of checks is less than 0
{ // numChecks is valid, so we can calulate the fees.
// Calculate checkFee - Use if/else if structure
const double MONTHLY_FEE= 10.00; // Base monthly fee
const double MIN_BAL= 400.00; // minimum balance
const double LOW_BAL_FEE= 15.00; // extra fee for low balance
for (int transaction = 0; transaction <=6; transaction++);
if (numChecks<20)
{
checkFee=(0.1*numChecks)+MONTHLY_FEE<<endl;
}
else if (numChecks<40 )
{
checkFee=( 0.08*numChecks)+MONTHLY_FEE<<endl;
}
else if (numChecks<60 )
{
checkFee=( 0.06*numChecks)+MONTHLY_FEE<<endl;
}
else (numChecks>60 )
{
checkFee=( 0.04*numChecks)+MONTHLY_FEE<<endl;
}
// Calculate totalFees
if (numChecks<20 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else if (numChecks<40 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else if (numChecks<60 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else if (numChecks>60 && acctBalance<MIN_BAL)
{
totalFees=checkFee+LOW_BAL_FEE<<endl;
}
else (numChecks<20 && acctBalance>MIN_BAL)
{
totalFees=checkFee
}
// Display results: The bank fee
cout<<"The bank fee this month is "<<totalFees<<endl;
}//end the loop
return 0;
}//end
And the errors I'm getting when I try to compile.
Error E2379 lab3.cpp 33: Statement missing ; in function main()
Error E2379 lab3.cpp 36: Statement missing ; in function main()
Warning W8004 lab3.cpp 115: 'transaction' is assigned a value that is never used in function main()
So basically my only problem is already in the title. Can anyone help out? Also I'm new to the C++ language so please be gentle. And if there's any other problems can you point it out to me? Thanks in advance.
You forgot the operators here
cout << "Your beginning balance is: " << acctBalance << endl;
^^
and here
cout << "The number of checks written were: " << numChecks << endl;
^^
Why are you including stdlib.h? I don't see where you are you are using it. If you need this header I'd recommend cstdlib instead.
As already pointed out in the comments you also made a semicolon instead of { which appears a few lines before in your code. Please consider spacing out your operators like this:
if(numChecks < 20) {
}
Using a consistent indention style would also improve readability.

C++ How to new line without chopping words

I am currently making a text game in c++. I am using a function that prints text one character at the time (to give a "narration" effect), which also goes to a new line to some condition defined by the function.
Here is the function:
void smart_print(const std::string& str, int spacer)//str is the printed message. spacer is the amount of space you want at the beginning and at the end of the cmd window
{
int max = Console::BufferWidth - (spacer * 2);
int limit = max;
ut.spacer(5);//this prints 5 spaces
for (int i = 0; i != str.size(); ++i)//this loop prints one character of the string every 50 milliseconds. It also checks if the limit is exceeded. If so, print new line
{
if (limit < 0)
{
cout << endl;
ut.spacer(5);
limit = max;
}
limit--;
std::cout << str[i];
Sleep(50);
}
}
The problem with this function, is that it chops the words, because it does a new line everytime the "limit" variable is less than 0, regardless if there is an incomplete word or not.
I made a sort of scheme to try to figure out how it should work correctly, but i can't manage to "translate" it into code.
1) Analyze the string, and check how long is the first word
2) Count the characters and stop counting when there is a space
3) Calculate if it can print the word (by subtracting the number of letters to max)
4) If the limit is exceeded, go to new line. Otherwise proceed to print the word one letter at the time
I really can't manage to make such function. I hope someone can help me out :P
Thanks in advance.
I think you should do something like checking if the current character is blank, using the std::isspace method like this:
// inside your for
if (limit < 0 && isspace(str[i]))
{
cout << endl;
ut.spacer(5);
limit = max;
}
limit--;
if(!isspace(str[i])) std::cout << str[i];
Sleep(50);
Note: I haven't tested the code so I am not 100% sure if it works correctly.

C++ simple array element comparison

Okay I don't know if this is even a valid question but I'm posting here because I don't know where else to turn with this. I just started studying programming this half year at a university and we just had the final exam, which I failed. Basically, there were 4 questions, and while the second one looked easy it was actually tricky and I just can't figure out how it should have been done.
Basically the problem is: There is a bank, and when people log in to do business, you need to write a program that records the time they logged in (0-24h), the minutes (0-59), the type of transaction they choose (1 for logging in with a bank card, -1 for logging out with the same bank card, 2 for money input into the account, -2 for withdrawal) and finally either their bank acc number (if they pressed 1 or -1 previously), or the amount they are withdrawing or putting in (if they chose 2 or -2).
Basically here is how we had to do it:
int n; //size of the array or number of ppl who transacted that day
cin >> n;
int bank[n][4];
for (int i=0; i<n; ++i)
{
cin >> bank[n][0];
cin >> bank[n][1];
cin >> bank[n][2];
cin >> bank[n][3];
}
This fills up all the info and then,
basically a sample input looked like this for 4 customers during the day:
11 40 1 458965
12 20 2 6000
15 40 -1 458965
16 25 -2 18000
Here is the part I could not solve:
Our test asked us: How many people were logged in from 12 o clock to 13:00 oclock?
At first I did
int count=0;
for (int i=0; i<n; ++i)
{
if (bank[i][0]==12)
{
count=count+1;
}
}
cout << count;
The problem with this, is that it does not account for people who log in before 12 with a 1 in the third column, but log out at later than 1 oclock with a -1. Which means they were still logged in from 12 to 1pm.
so then I did
int count=0;
for (int i=0; i<n; ++i)
{
if (bank[i][0]==12)
{
count=count+1;
}
if (bank[i][2]==-1)
{
count=count+1;
}
}
cout << count;
but then I realized that this would count some logins twice, because if they logged in at 12 with a 1 for example, then logged out at 3 o clock with a -1 it would count that one person twice.
It also asked us what is the longest period that any person was logged in, assuming the bank kicks everyone off at 24:00. I honestly am not even sure how to even begin that one.
EDIT: SORRY i edited a bunch of stuff to make it clearer and correct code. I'm not too good at this yet forgive my mistakes
I didn’t know how the bank system works. So I made a minimal example for you.
I also didn't know if you used classes before, so I wrote it without.
I cleaned your code a bit:
//Use these enums
enum action { action_login = 1, action_logout = -1, action_input = 2, action_output = -2 };
enum information {information_time_h, information_time_m, information_action, information_bankNumber};
//Place this in the function you have
int peapelToInput = 0; //size of the array or number of ppl who transacted that day
cin >> peapelToInput;
for (int i=0; i<peapelToInput; ++i)
{
//Maby add error handeling? When some one inputs a 'a', it won't do what you want.
cin bank[i][information_time_h];
cin bank[i][information_time_m];
cin bank[i][information_action];
cin bank[i][information_bankNumber];
}
As you can see, I made the code cleaner by adding enums. This makes developing a lot easier.
The login code:
int count=0;
int bankSize = bank.size(); //I guess it's a vector?
for (int i=0; i < bankSize; ++i)
{
if (bank[i][information_time_h] == 12 && bank[i][information_action] == action_login)
count++;
}
cout << "logins at 12:00 - 12:59:" << count << endl;
You can do 2 checks in 1 if, I increment count when they were logedin from 12:00 - 12:59. Do you need exclude people that were loggedout?
The longest time code:
//A function to search when he is logedout
int findLogoutIndex(int start, int accountNumber, XXX bank)
{
int bankSize = bank.size();
for (int i=start; i < bankSize; ++i)
if( bank[i][information_action] == action_logout && bank[i][information_bankNumber] == accountNumber)
return i;
return -1; //Handle this error
}
//And how it workes
int logenst = 0;
int indexLongest = 0;
int bankSize = bank.size(); //I guess it's a vector?
for (int i=0; i < bankSize; ++i)
{
if( bank[i][information_action] != action_login )
continue;
int logoutIndex = findLogoutIndex(i,bank[i][information_bankNumber],bank);
//check if logoutIndex is not -1, or handle the error on an other way.
int loginTimeHour = bank[logoutIndex][information_time_h] - bank[i][information_time_h];
int loginTimeMinute = bank[logoutIndex][information_time_m] - bank[i][information_time_m];
int loginTime = (loginTimeHour * 100) + loginTimeMinute;
if( logenst < loginTime)
{
logenst = loginTime;
indexLongest = i;
}
}
cout << "longest is: H:" << bank[indexLongest][information_time_h] << " M: " << bank[indexLongest][information_time_m] << endl;
You don't need to keep the time format, this way makes comparing a lot easier. Just save the longest login time and the index number of it. That way you can easily access all the data you want.
I didn't take the time to write "good code". But you asked how it can be done, I guess this is good enough to understand it?
I didn't test the code and wrote it in Notepad. So I don't know if it will compile.
The first thing that you need to know is what the questions are actually asking. In the first case, How many people were logged in from 12 o clock to 1 oclock? can mean multiple things. It could mean how many people were logged in during the whole period or how many people were logged in at any given time between those two hours. The difference is whether someone that logs in at 12:15 and logs out at 12:30 is counted or not. The second question is calculating the longest period someone was logged in, and that can be done at the same time.
One possible approach would be managing a lookup table from user id to login times. You read the input linearly, whenever someone logs in you add an entry (acct, time) into the table. When they log out you lookup the account number and calculate the difference of times. If the difference is greater than the maximum you store the new maximum.
For the first question, at 12 you can create a set of the people that was logged in from that lookup table. Whenever someone logs out between that time and 1 you find whether the person was in the set and you remove it if so. When you find the first operation after 1, the set contains the account numbers of all the people that was logged in for the whole period from 12 to 1.
If the question was getting all people that was logged at any time in the period, instead of removing from the set those users that log out before 1, you need to include new users that log in inside the period. At the end of the period the set contains all users that were logged in at any time within the period.
You only need to perform a single pass over the input data which means that you don't even need to store all of the transactions in memory, only the map/set required above. The overall cost of the operation is O(n log n) on the number of operations. (Disclaimer: I haven't done the math, this is a hunch :))
Haven't tested this. Nevertheless, the process followed should be correct.
I'm sure this can still be optimized in terms of execution speed.
Also, I assume by time 12 you mean 12:00 and by time 1 you mean 13:00.
int main()
{
int answer = 0;
// For each transaction
for ( int i = 0; i < count; i++ ) {
// If logged in before 12:00
// bank[i][2] > 0 tells you user logged in.
if ( bank[i][0] < 12 && bank[i][2] > 0 ) {
// Loop through each following transaction.
for ( int j = i + 1; j < count; j++ ) {
// If logged out after 13:00
if ( bank[j][0] > 13 && bank[j][2] < 0 ) {
// Now to check if it was the same user who logged in earlier - how?:
// Only way to differentiate is by comparing the transaction amounts and types.
if ( (bank[i][3] == bank[j][3]) && (bank[i][2] == -1*bank[j][2]) ) { // log-in code = -1 * log-out code.
answer++; // Number of transactions that spanned from before 12:00 till after 13:00.
// Remember, a single person can't have multiple log-ins at the same time. ( assumption )
}
}
}
}
}
}

C+ program involving functions...Please help me

I am having a hard time with two functions. Here are the project instructions:
Assignment:
Write a program which keeps track of the number of roaches in two adjacent houses for a number of weeks. The count of the roaches in the houses will be determined by the following:
The initial count of roaches for each house is a random number between 10 and 100.
Each week, the number of roaches increases by 30%.
The two houses share a wall, through which the roaches may migrate from one to the other. In a given week, if one house has more roaches than the other, roaches from the house with the higher population migrate to the house with the lower population. Specifically, 30% of the difference (rounded down) in population migrates.
Every four weeks, one of the houses is visited by an exterminator, resulting in a 90% reduction (rounded down) in the number of roaches in that house.
Here's my code:
#include <iostream>
#include <cmath>
using namespace std;
int house, increase, roaches, moreRoaches, fewerRoaches, filthyBeasts, change; // My variables for my four functions
int initialCount(int house);
int weeklyIncrease(int increase);
double roachesMigration(int moreRoaches, int fewerRoaches, int change);
int exterminationTime (int filthyBeasts);
// My four function prototypes
int main()
{
int houseA, houseB;
houseA = initialCount(houseA); //Initializing the initial count of House A.
houseB = initialCount(houseB); //Initializing the initial count of House B.
int week = 0;
for (week = 0; week < 11; week++) // My for loop iterating up to 11 weeks.
{
houseA = weeklyIncrease(houseA);
houseB = weeklyIncrease(houseB);
cout << "For week " << week << ", the total number of roaches in House A is " << houseA << endl;
cout << "For week " << week << ", the total number of roaches in House B is " << houseB << endl;
if((houseA > houseB)) // Migration option 1
{
roachesMigration(moreRoaches, fewerRoaches, change);
}
else if((houseB > houseA)) // Migration option 2
{
roachesMigration(moreRoaches, fewerRoaches, change);
}
if ((week + 1) % 4 == 0) // It's extermination time!
{
if ((rand() % 2) == 0) // Get a random number between 0 and 1.
{
houseB = exterminationTime(houseB);
}
else
{
houseA = exterminationTime(houseA);
}
}
}
return 0;
}
int initialCount(int house) // Initializing both houses to random numbers between 10 and 100.
{
int num;
num = (rand() % 91) + 10;
return num;
}
int weeklyIncrease(int increaseHouses) // Increasing the roaches in both houses by 30% weekly.
{
int increase = 0;
increase = (increaseHouses * .3) + increaseHouses;
return increase;
}
double roachesMigration(int moreRoaches, int fewerRoaches, int change)
{
more -= change;
fewer += change;
change = ((more - fewer) * .3);
return change;
}
int exterminationTime(int filthyBeasts) // Getting rid of the filthy little beasts!
{
filthyBeasts = (filthyBeasts * .1);
return filthyBeasts;
}
The issues are with the migration and extermination functions. My code runs fine, but at weeks 4 and 8, the randomly selected house should get exterminated, and the number of roaches in that house should be 90% less than the previous week. What do you guys think I should do to correct these issues? I really need all the help I can get!
Regarding this line:
roachesMigration(change);
change is not declared in your main function, hence the error. Also, roachesMigration function expects 3 parameters and not 1.
The variable change is not a global variable, but appears inside main (so it has no meaning inside main).
Your roachesMigration fonction is declared with three formal arguments (without default values), but you use it with one actual argument.
Ask your compiler to give you all the warnings and to produce debugging information (g++ -Wall -g on Linux). Improve the code till you get no warnings.
Learn to use a debugger (e.g. gdb on Linux).
Have fun.
Depending on the instructor, you will get zero marks for this code, even if you can get it to work perfectly! This is because you have not used any object orientated design in building your code. In C++, that means classes.
What sort of object do you need for this problem. A house!
What sort of attribute should your house have? Roaches!
So something like this:
class cHouse
{
int MyRoachCount;
...
};
If you start fresh, like this, you will find things start to fall neatly into place.
One possible way to handle the migration is like this pseudocode:
// compute size of migration
count = migration(houseA, houseB)
if (houseA < houseB)
add count to houseA
subtract count from houseB
else
add count to houseB
subtract count from houseA