wanting to limit characters for things such as Date of birth and some cant have an incom of £555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555 etc
Printable View
or that lol
Yes, but that is not an input problem, it is a data validity problem.
Don't tell your user "You have entered an amount of dollars which is written with 52 chars, and that is too long" but tell him "cannot process orders of more than 1 million dollars"
The user input is perfectly legal. Then it is you responsibility to make sure the the input is relevant. The difference is subtle, but important.
On a side note, if you create a "date" class, you can then write "cin >> myDate", if you redefine the operator>>. Then, you can manually define that operator to reject an input which is not a valid date, but valid numeric (like if the user enters 52/17/19997).
I completely agree with this method, and have used it severall times, but isn't it essentially the same thing, with more safety? You say "parse from the string what you need using stringstreams", aren't you just going to use operator>> on your stringstream?
I was trying to explain that using operator>> is usually safer than combining string search and calls to things like atoi. Calling it on cin directly, or on a stringstream built from a getlined string is essentially the same thing, IMO.
Just seems weird that you would advise against calling operator>>. Did you mean "calling operator>> directly on cin"?
lol anyways thanks guys, i guess its working atm so going to leave it be lol as i said :) thanks
Yes of course I meant not to call operator >> on cin. I find it much more preferable to get all input as a string and parse accordingly. It certainly makes error checking easier and cin is always in a usable state. I know some favour checking the flags, then ignoring chaff left in the buffer and dealing with mixing of operator >> and getline and clearing error flags, but for me thats just too much hassle when there is a simpler typesafe alternative available. With templates this can almost become a write once and reuse for the rest of your coding life option. Those templates would deal with the general cases and you would only need to supplement the code rarely for more special situations.
You dont always use operator >> on stringstreams to extract what you want but its the most common option. The templates mentioned above would probably use it, mine do.
I note that Lindley's example would not regard input such as "123hello" as bad input. If you want to detect such cases of valid followed by invalid input, then you should change it to:
Code:if (!(valstream >> val) || !valstream.eof())
cout << "bad input";
Wouldn't that also not work? I thought eof was set to true only once a read past eof is attempted?
I might be wrong, but wouldn't the code be something like this? where we create a dummy string to do one last read before checking for EOF?
Code:string isEOFString;
if (!(valstream >> val) || (valstream >> isEOFString, !valstream.eof()))
cout << "bad input";
Yes, but for reasons that I have not fully researched into, the behaviour is slightly different for stringstreams.Quote:
Originally Posted by monarch_dodra
ack and it has just gone to pot again >< mk here is the whole code.......wanting to complete it as soon as possible as my assignment is due in knowing me probs made it more long winded than it should be......
Code://This program shows the person whether or not they are eligible for Working Tax credit
//based on their income how many hours they work and how old they are.
//If a couple is checkin whether they are eligible it will combine both of their income.
//After checking if eligible, it will then give them an estimated value.
//Created on 23rd November 2009 by Daniel Hirst
#include <iostream>
#include <conio.h>
#include <time.h> // Allows detection of current time
#include <stdio.h>
#include <stdlib.h>
using namespace std;
//Variable Declarations
int age;
char birthyr[4];
char income[7];
char wrkhrs[2];
char choice;
int credit; //Working Tax Credit
int curryr; //Current Year
//functions
void Menu();
void SingleEnq()
{
while((atoi(birthyr)) == 0)
{
cout<<"Please enter your year of birth(YYYY): ";
cin>>birthyr;
if((atoi(birthyr))==0)
{
cout<<"Birth Year is not valid"<<endl;
(atoi(birthyr)) == 0;
}
}
while((atoi(income)) == 0)
{
cout<<"Please enter your yearly Income: "<<char(156);
cin>>income;
if((atoi(income))==0)
{
cout<<"Yearly Income is not valid"<<endl;
(atoi(income))==0;
}
}
while((atoi(wrkhrs)) == 0)
{
cout<<"Please enter how many hours you work in a week: ";
cin>>wrkhrs;
if((atoi(wrkhrs))==0)
{
cout<<"Work Hours is not valid"<<endl;
(atoi(wrkhrs)) == 0;
}
}
age = curryr - atoi(birthyr);
cout<<"Your age is "<<age<<endl;
cout<<"You work "<<wrkhrs<<" hours a week"<<endl;
cout<<"Your yearly income is "<<char(156)<<income<<endl<<endl;
while ((choice!='Y') && (choice!='y') && (choice!='N') && (choice!='n'))
{
cout<<"Is the above data correct? (Y/N): ";
cin>>choice;
cout<<endl;
if ((choice!='Y') && (choice!='y') && (choice!='N') && (choice!='n'))
{
cout<<"Choice not valid"<<endl;
cin.clear();
}
else if ((choice=='N') || (choice=='n'))
{
memset(birthyr, 0, sizeof(birthyr)); // resets char variable to 0
memset(income, 0, sizeof(income));
memset(wrkhrs, 0, sizeof(wrkhrs));
credit=0;
choice==0;
system("cls");
return SingleEnq();
}
else if ((choice=='Y') || (choice=='y') )
{
if((age>25) && (atoi(wrkhrs)>30) && (atoi(income)<11700))
{
if(atoi(income)<=8612)
{
credit=1180;
}
else if((atoi(income)>8612) && (atoi(income)<=11700))
{
credit=665;
}
cout<<"Using the data provided, we have found you are eligible "<<endl;
cout<<"for "<<char(156)<<credit << " of Working Tax Credit"<<endl<<endl;
cout<<endl;
}
else
{
cout<<"Sorry, you are not eligible for any working tax credit because: "<<endl;
if(age<25)cout<<"- You are under 25"<<endl;
if(atoi(wrkhrs)<30) cout<<"- You work less than 30 hours a week"<<endl;
if(atoi(income)>11700) cout<<"- You earn more than "<<char(156)<<"11700 yearly"<<endl;
}
}
}
getch();
system("cls");
choice==0;
return;
}
void CoupleEnq()
{
int page;
char pbirthyr[5];
char pincome[6];
char pwrkhrs[3];
int incometot;
while((atoi(birthyr)) == 0)
{
cout<<"Please enter your year of birth(YYYY): ";
cin>>birthyr;
if((atoi(birthyr))==0)
{
cout<<"Birth year not valid"<<endl;
}
}
while((atoi(income)) == 0)
{
cout<<"Please enter your yearly Income: "<<char(156);
cin>>income;
if((atoi(income))==0)
{
cout<<"Yearly Income not valid"<<endl;
}
}
while((atoi(wrkhrs))==0)
{
cout<<"Please enter how many hours you work in a week: ";
cin>>wrkhrs;
if((atoi(wrkhrs))==0)
{
cout<<"Work Hours not valid"<<endl;
}
}
while((atoi(pbirthyr))==0)
{
cout<<"Please enter your partners year of birth(YYYY): ";
cin>>pbirthyr;
if((atoi(pbirthyr))==0)
{
cout<<"Partner Birth Year not valid"<<endl;
}
}
while((atoi(pincome))==0)
{
cout<<"Please enter your partners yearly Income: "<<char(156);
cin>>pincome;
if((atoi(pincome))==0)
{
cout<<"Partners Yearly Income not valid"<<endl;
}
}
while((atoi(pwrkhrs))==0)
{
cout<<"Please enter how many hours your partner works in a week: ";
cin>>pwrkhrs;
if((atoi(pwrkhrs))==0)
{
cout<<"Partners Work Hours not valid"<<endl;
}
}
age = curryr - (atoi(birthyr));
page= curryr - (atoi(pbirthyr));
incometot = (atoi(income))+ (atoi(pincome));
cout<<"Your age is "<<age<<endl;
cout<<"You work "<<wrkhrs<<" hours a week"<<endl;
cout<<"Your yearly income is "<<char(156)<<income<<endl;
cout<<"Your partners age is "<<page<<endl;
cout<<"You partner works "<<pwrkhrs<<" hours a week"<<endl;
cout<<"Your partners yearly income is "<<char(156)<<income<<endl;
cout<<"Your combined income is "<<char(156)<<incometot<<endl;
while ((choice!='Y') && (choice!='y') && (choice!='N') && (choice!='n'))
{
cout<<"Is the above data correct? (Y/N): ";
cin>>choice;
cout<<endl;
if ((choice!='Y') && (choice!='y') && (choice!='N') && (choice!='n'))
{
cout<<"Choice not valid"<<endl;
cin.clear();
}
else if ((choice=='N') || (choice=='n'))
{
memset(birthyr, 0, sizeof(birthyr)); // resets char variable to 0
memset(income, 0, sizeof(income));
memset(wrkhrs, 0, sizeof(wrkhrs));
memset(pbirthyr, 0, sizeof(pbirthyr));
memset(income, 0, sizeof(pincome));
memset(wrkhrs, 0, sizeof(pwrkhrs));
memset(wrkhrs, 0, sizeof(incometot));
credit=0;
choice==0;
cout<<endl;
system("cls");
return CoupleEnq();
}
else if ((choice=='Y') || (choice=='y'))
{
cout<<endl;
if (age>= 25 && atoi(wrkhrs)>=30 && incometot < 16300 && page>= 25 && atoi(pwrkhrs)>=30)
{
if(incometot<=8612)
{
credit=2880;
}
else if((incometot>8612) && (incometot<=11700))
{
credit=2370;
}
else if((incometot>11700) && (incometot<=12000))
{
credit=1630;
}
else if((incometot>12000) && (incometot<=14000))
{
credit=890;
}
else
{
credit=150;
}
cout<<"Using the data provided, we have found you and your partner are eligible "<<endl;
cout<<"for "<<char(156)<<credit << " of Working Tax Credit"<<endl<<endl;
}
else
{
cout<<"Sorry, you are not eligible for any working tax credit because: "<<endl;
if(age<25) cout<<"- You are under 25"<<endl;
if((atoi(wrkhrs))<30) cout<<"- You work less than 30 hours a week"<<endl;
if(page<25) cout<<"- Your partner is under 25"<<endl;
if((atoi(pwrkhrs))<30) cout<<"- Your partner works less than 30 hours a week"<<endl;
if(incometot>16300) cout<<"- Your combined wage is over "<<char(156)<<"16300 a year"<<endl;
}
}
}
getch();
system("cls");
choice==0;
return;
}
void Menu()
{
int mchoice=0;
system("cls");
while(mchoice!=3)
{
memset(birthyr, 0, sizeof(birthyr)); // resets char variable to 0
memset(income, 0, sizeof(income));
memset(wrkhrs, 0, sizeof(wrkhrs));
credit=0;
cout<<"Welcome to the Working Tax Credit Calculator. In order to process your enquiry"<<endl;
cout<<"further we need to know whether you are enquiring as a couple. Please choose "<<endl;
cout<<"from the following options:"<<endl<<endl;
cout<<"1. Enquiry for Singles"<<endl;
cout<<"2. Enquiry for Couples"<<endl;
cout<<"3. Exit"<<endl<<endl;
cout<<"Menu choice: ";
cin>>mchoice;
cout<<endl;
if (mchoice==1)
{
system("cls");
SingleEnq();
}
else if (mchoice==2)
{
system("cls");
CoupleEnq();
}
else if (mchoice==3)
{
cout<<endl;
cout<<"Thank you for using the Working Tax Credit Calculator";
getch();
exit(1);
}
else
cout<<"Please enter a valid menu choice"<<endl<<endl;
}
}
void main()
{
time_t t = time(0);
tm time = *localtime(&t);
curryr = time.tm_year + 1900;
Menu();
getch();
}
This does not do what you think it does. "clear" merely removes the errors status from your stream. It does not remove any corrupt data, or empty your stream or anything like that. If you are trying to read an int, and the data in your stream is "apples", you will fail forever.
This is what you need to do:
Or just read this guide. I really think you need it. It'll help.Code:std::cin.clear(); //Remove error status
std::cin.ignore(255, '\n'); //Remove any data left in the stream.
http://www.parashift.com/c++-faq-lit....html#faq-15.3
On a side note, I really think you need to try to learn the "C++ way" of doing things, rather than the "C way".
Also, try concentrating on the scope of your variables, and what they should be. For example, the variable "choice" is global, but mchoice is not?
Another weird thing in your code is that every now and then you write things like:
What exactly do you think this does? I think the first one does not do what you want (I don't know what you want though), and the second one, might be a typo'ed = turned ==.Code:cout<<"Birth Year is not valid"<<endl;
(atoi(birthyr)) == 0;
or
memset(wrkhrs, 0, sizeof(wrkhrs));
credit=0;
choice==0;
system("cls");
return SingleEnq();
Finally, as we said, don't work with char arrays (or string). If your data represents a number, put it in a number, and work with that. Don't atoi() every time you need the birthyear. This is just god awful:
I can't really help you more, since you never even said what was wrong, which is basically the first thing you should have told us...Code:age = curryr - atoi(birthyr);
Sorry, the main reason for the == on the atoi's, they are mainly copied and pasted and as for the == on the choice, moans at me if i use a single which confuses me as it should work :/ but meh sorry, first yr on this HND and last time i coded was in VB, DarkBasic, HTML etc etc....
What im wanting (as seen with the size of the char variables) is to LIMIT the variables to a certain amount of characters so the user cannot exceed it, i also want to display the variable, on the second time of antering an illegal date of birth, the age tends to go to 6 figures or so......-sigh-.......sorry :( just want it to work, and as u said all ive rlly done is naffed it up so to speak :/. The other thing is im not wanting this code so my tutor can sense that I havent coded it etc...
firstly, sorry for the double post
birthyr
i want limite to 4 DIGITS, such as 1979 and not 1974538134753 or fsdfsdff or 19ddsfdsfd
income
i want to be limited to 6 or 8 digits, not sure, dont think i will allow 2 decimal places as that does complicate things
wrkhrs
2 digits, as 1 person isnt really going to work over 100 hours a week (correct me if im wrong)
choice
either "Y","y","N" or "n"
credit
is ok as is as ppl dont mess with this, calculated automatically
curryr
is ok as is as ppl dont mess with this, calculated automatically
edit: as for the scope of my choice variable, reason i made it global is because it is used in more than one function