i'm so sory because i made mistake when asking about this before..
so here i'll make correction in this post....

actually what i want to ask is why my cin.fail() code do not works??

i want this program to ask the user back the same question if the user enter the wrong data type input....
i am using do while loop plus with the cin.fail() in my code but it seems to do the infinite loop when the user enter the wrong data type input...

below is my full code...

Thanks for helping :)

#include <iostream>
#include <iomanip>
using namespace std;

int main () {

//A class named record to organize the data more easily
struct record{
   int id;
   string name;
   double price;
   int quantity;
   double sale;
   };

  record product[100];
  int id[100];


      int i=0;
      char answer;

      cout<<"--------------------------------------------------------------------------------";
      cout<<"\t\t\t\tCASH RECEIPT PROGRAM"<<endl;
      cout<<"--------------------------------------------------------------------------------";
      cout<<endl;



do{



     do{

        cout << "Enter the Product id : ";
        cin >> product[i].id;

    }while(!isdigit(i));//this is actually what i want t do...//but whats wrong??????


cout<<endl;

      cout << "Enter the Product Name : ";
      cin >> product[i].name;


      cout << "Enter the Price For Single Item : ";
      cin >> product[i].price;

      cout << "Enter The Quantity : ";
      cin >> product[i].quantity;

      cout<<endl;

      cout << "Would You like to enter another product? (Y/N) ";
      cin >> answer;


      i++;

      cout<<endl;

      }while(answer == 'y' || answer == 'Y');


cout<<"--------------------------------------------------------------------------------";
cout<<"ID |"<<setw(13)<<"ITEM |"<<setw(12)<<"PRICE |"<<setw(10)<<"QTY |"<<setw(10)<<"SALE"<<endl;
cout<<"--------------------------------------------------------------------------------";

 int index;
for(index=0; index<i; index++){

product[index].sale=(product[index].price)*(product[index].quantity);

// Display all the info about that product
cout <<product[index].id<<setw(10)<<product[index].name<<setw(10)<<"$"<<fixed<<setprecision(2)<<product[index].price<<setw(10)
<<product[index].quantity<<setw(10)<<product[index].sale;

cout<<endl;
}

cout<<endl;

int total = 0;
for(int counter=0; counter < i; counter++)
{
total += product[counter].sale;
}

cout<<"TOTAL SALE IS :"<<total;
cout<<endl;

double payment;

cout<<"PLEASE ENTER THE PAYMENT RECEIVED :";
cin>>payment;
cout<<endl;

while (payment<total){
cout<<"The Amount Of Payment Is Insufficient !"<<endl;
cout<<"PLEASE ENTER THE PAYMENT RECEIVED :";
cin>>payment;
}

cout<<endl;
cout<<"------------------------"<<endl;
cout<<"TOTAL SALE      :$"<<total<<endl;
cout<<"RECEIVE PAYMENT :$"<<payment<<endl;
cout<<"BALANCE         :$"<<payment-total<<endl;
cout<<"------------------------";
cin.get();
}
char test;
     do{        
		 cout << "Enter the Product id : ";     
		 cin >> test; 
	 }while(isdigit(test)==0);
	 product[i].id = test;

	 system("pause");
 	return 0;
}

Hey,

IsDigit only works with characters.

You'd have to do something like above. (Although if a user inputs a string it effectively calls the loop X times.

Input X will fail and loop, Input 13556 will be accepted, Input test will loop 4 times, but that's IsDigit for you.

That sorted?

Lilly

ps. System pause was just for my debugging, can remove that

Edited 6 Years Ago by Lilal: n/a

The stream will fail on line 37 if something that is not a digit or a minus sign (or possibly a decimal? Can't remember) is entered. Once the cin stream is in a failed state, if you do not clear it, it will remain in a failed state.

If the object is to allow recovery for non-numerical input, don't read in the user input as an integer. Read it in as a string and test the string for good input. If non-digits are entered, prompt again for user input. If valid input was entered, convert the string to an integer and continue.


Input X will fail and loop, Input 13556 will be accepted, Input test will loop 4 times, but that's IsDigit for you.

There will be no looping. 1 will be accepted as input. 3556 will remain in the stream. id will be assigned to be '1', which in Acscii is 49. Your solution deals with illegal input just fine, but it will exit the loop after the first digit.

how if i use cin.fail() instead of isdigit()????

do{

cout << "Enter the Product id : ";

cin >> product.id;

}while(cin.fail());

this is still wrong....h0ow should i fix this???

how if i use cin.fail() instead of isdigit()????

do{

cout << "Enter the Product id : ";

cin >> product.id;

}while(cin.fail());

this is still wrong....h0ow should i fix this???

Once a stream has failed, it will stay failed until it is cleared, so if you were to take this approach, you'd have to clear the stream at the top of the loop.

http://www.cplusplus.com/reference/iostream/ios/clear/

That would solve at least one of your problems, but others would still remain.

I again propose what I proposed in post 3. Read in the data as a string, test whether it is good data (you can loop through using isdigit for this), then if the data is good, after the loop, convert the string to an integer. atoi does this well, so convert the string to a const char* using c_str (), then use atoi.

atoi is often frowned upon due to its lack of error checking, but that's not relevant here because you've already done the error checking for non-digits before the conversion. Some people might suggest using a stringstream instead, which also works, but I think atoi works fine here so you don't need a stringstream. 6 of one, half a dozen of the other, I think. There's more than one way to do this.

This article has been dead for over six months. Start a new discussion instead.