C++ help, again.

Trio

New Member
I should make a single thread so I can post all my questions, lol.

So I did an excersis out of the book and it worked well. It's a program that asks the user to input three number, then the program orders it from least to greatest.

I decided to add an if statement so incase the user inputs the same number for the three variable, it'll prompt the user to input another three numbers. I also added a while loop so this would be possible, because I didn't add that bit until the last few lines of the program. I included a break so it wouldn't be an infinite loop.

Now I'm trying to add another if statement incase the user enters the wrong data type (letter instead of a number). The problem is, I'm not sure how to compare data types. I've tried using a bool data type and adding the variables, so if it comes out to false, the clear function would activate and have the user input numbers again. Here's the program, and sorry for all the braces. I'll highlight the problem in red.



Code:
//This program will ask the user to input three number and ordered from least to greatest
#include <iostream>

using namespace std;

int main()
{
     double a,b,c,check;
     [COLOR="Red"]a=0, b=0, c=0;[/COLOR]
     cout<<"Enter two numbers. They will be ordered from least to greatest."<<endl;
     cin>>a>>b>>c;
   [COLOR="red"]  check = a+b+c;
     bool clear;
     clear = check;[/COLOR]

     while (cin) //as long as there is input, the loop will begin
     {
      [COLOR="red"] {
		
       if (!clear)
       {
         cin.clear();
         cout<<"You can't enter letters. Enter three numbers"<<endl;
         cin>>a>>b>>c;
       }
		
       }[/COLOR]

       if (a>b && a>c)
       {
         if (b>c)
           cout<<"The numbers, from least to greatest are "<<c<<" "<<b<<" "<<a<<endl;
         else 
           cout<<"The numbers, from least to greatest are "<<b<<" "<<c<<" "<<a<<endl;
         break;		//If a>b>c || a>c>b, break will end the loop
       }
       if (b>a && b>c)
       {
         if (a>c)
           cout<<"The numbers, from least to greatest are "<<c<<" "<<a<<" "<<b<<endl;
         else
           cout<<"The numbers, from least to greatest are "<<a<<" "<<c<<" "<<b<<endl;
         break;		//If this is the situation, the program will end the loop
       }
       if (c>a && c>b)
       {
         if (a>b)
           cout<<"The numbers, from least to greatest are "<<b<<" "<<a<<" "<<c<<endl;
         else
           cout<<"The numbers, from least to greatest are "<<a<<" "<<b<<" "<<c<<endl;
         break;		//If this is the situation, the program will end the loop
       }
       if (a==b && b==c)		//Incase alike numbers are inputted
       {
         cout<<"The numbers are the same, enter them again."<<endl;
         cin>>a>>b>>c;		//Reinput the numbers and start the loop over again
       }
    }

system("pause");
return 0;
}

I was thinking of adding something like:

bool check;
check= ( (a+b+c)==int) );

if (check)
cin.clear();
.
.
.

or:

if ( (a+b+c)==int) );
cin.clear();
.
.
.

I'd appreciate any sort of help.
 
Last edited:
I don't have a compiler here, I want to try a few things first so that I don't tell you something silly :)

Check back later tonight.
 
You are right the red part is the problem. Look at it again, I'll give you a way to correct it but I'd like it better if you can at least identify why it doesn't work. There's a little bit of other icky spots but we can look at them after.
 
Last edited:
Honestly, the only issue with those parts that I can see is adding the three variables together, using the ! in the if statement, and the braces before and after the if statement.

I added the three variables because I thought it would create a fail state in the check variable, so it would evaluate to false. Well, after typing that, the ! in the if doesn't make much sense. It actually does the opposite of what I want. The reason I stored check in clear is because it'll have a true/false answer, but I just remembered that I can use plain numbers to represent true or false. I can use a number above 0 to represent true, and 0 to represent false. So, if check goes into the fail state, it'll evaluate to 0- false. Is this a solution?

I gave the three values the value 0 because when the input is cleared, they'll reset themselves to the those values, thus they'll have the same value and jump all the way to the bottom and execute this part:

{
cout<<"The numbers are the same, enter them again."<<endl;
cin>>a>>b>>c; //Reinput the numbers and start the loop over again
}

I added that before I thought I should fix the error message and make it so it tells the user that they can't use letters:

cin.clear();
cout<<"You can't enter letters. Enter three numbers"<<endl;
cin>>a>>b>>c;

I wasn't thinking clearly when I wrote that part, so that's why it doesn't make very much sense.

I also remember reading in my book that I have to use the cin.ignore function to remove the input after an input failure, but I left that out because I thought it'd still work (it was sort of an experiment).

And I guess the braces I added before and after the if doesn't have a reason to be there, but the ones within it hold the if statement together.

Maybe there's something in the book that can help me out. I won't be able to read it until later though. I have to catch up with my other classes, lol. So am I wrong about those parts? Maybe try giving me a day to solve this, lol.
 
Last edited:
cin.clear will just clear error flags. you need to ignore the characters in the input buffer still or it will continue to error out. When cin hits something that doesn't fit the type it's leading it flags .fail()

I would probably use get and parse the values out:
Code:
int main () {
  char first, last;

  cout << "Enter your first and last names: ";

  first=cin.get();
  cin.ignore(256,' ');

  last=cin.get();

  cout << "Your initials are " << first << last;

  return 0;
}
 
Looking at this again I didn't really explain why, the reason I say use cin.get() instead of cin >> ... is because I find get works like I expect it to and using >> doesn't. If I try to use clear/ignore conbined with >>, I have problems making it work.

Also, using while(cin) isn't the best idea. I would suggest setting a boolean that breaks the loop instead. It makes for much cleaner code. break; is not your friend unless you have a switch statement :)
 
Sorry for replying late. Well I went to the programming lab to get some help. The guy working there really helped me a lot, and I solved part of the problem.

Looking at the older code, I don't think I was very far from the solution. What I did was convert the input a,b,c to int using the cast operator static_cast. This way, if the person inputs a character instead of a number, I'll get the ASCII collated sequence, and then I can compare that with all the ASCII characters so the input would be false. Here's what I mean:

Code:
double a,b,c, check_a, check_b, check_c;
cout<<"Enter three numbers"<<endl;
cin>>a>>b>>c;
check_a = static_cast<int>(a);
check_b = static_cast<int>(b);
check_c = static_cast<int>(c);

if ( (check_a >0 || check_b >0) || checkc > 0)
     {
     cin.clear();
     cin.ignore(500, '\n');
     cout<<"You can't input a character. Enter three numbers."<<endl;
     cin>>a>>b>>c;
     }

The only problem with this is if the user inputs a string instead of just a single character, the code won't work and the program will end. Also, I would be converting numbers as well as characters into an int, then compare it to 0. If the user inputs a number above 0, it activate the if and have the user re-enter the code. But, if none of the numbers were an input failure, the cin.clear() won't activate, but the user might still have to enter new numbers.

So you were right about the cin.ignore, I did have to add that. Now I understand that it really is needed for using the cin.clear (and btw, what's a parse?). I don't understand your code, the part with the cin.ignore. Would that ignore the space inbetween the name, the space I mean (' '). Or wouldn't it ignore the next name?

Also, what would happen if I use the >> operator instead of the . operator? I learned from the book that '.' access the member of the variable. I didn't understand why it wasn't used to access the members of the cout, like endl, even though the syntax for the cout is cout<<manipulator;. And a final question: why is using while (cin) a bad idea? I tried thinking of another way to activate the loop while I was writing the code, but I couldn't think of anything. I could do something like:

Code:
while ( (a>=0 && b>=0) && c>=0)

But then numbers lower than the number 0 won't activate the loop.
 
Last edited:
Now I understand that it really is needed for using the cin.clear (and btw, what's a parse?). I don't understand your code, the part with the cin.ignore. Would that ignore the space inbetween the name, the space I mean (' '). Or wouldn't it ignore the next name?
Parsing is reading through some input and pulling out the parts you want.
Also, what would happen if I use the >> operator instead of the . operator? I learned from the book that '.' access the member of the variable. I didn't understand why it wasn't used to access the members of the cout, like endl, even though the syntax for the cout is cout<<manipulator;.
You can use >>, all it is an operator>> method of ostream. I've found that ignore/clear and what not don't work well when I use >> to read input. I don't know why, it's just something that's caused me grief before. Here's why << works for cout (cin is similar)
Code:
basic_ostream& operator<< (bool& val );
basic_ostream& operator<< (short& val );
basic_ostream& operator<< (unsigned short& val );
basic_ostream& operator<< (int& val );
basic_ostream& operator<< (unsigned int& val );
basic_ostream& operator<< (long& val );
basic_ostream& operator<< (unsigned long& val );
basic_ostream& operator<< (float& val );
basic_ostream& operator<< (double& val );
basic_ostream& operator<< (long double& val );
basic_ostream& operator<< (void*& val );
basic_ostream& operator<< (basic_streambuf<charT,traits>* sb );
basic_ostream& operator<< (basic_ostream& ( *pf )(istream&));
basic_ostream& operator<< (basic_ios<charT,traits>& ( *pf )(basic_ios<charT,traits>&));
basic_ostream& operator<< (ios_base& ( *pf )(ios_base&));
why is using while (cin) a bad idea? I tried thinking of another way to activate the loop while I was writing the code, but I couldn't think of anything.
I think the reason your loop starts is because cin >> a >> b >> c; leaves the \n in the input stream. What I would do is assign a boolean as false then set it to true once your input is good.

For character/digit validation if you are only accepting int you can read the values as characters and use isdigit to determine if you can turn it into an integer with the atoi function.
 
Back
Top