While loop, while !=float

So I was wanting to have a while loop, which loops until the user inputs a float, so basically if the user inputs words the loop will occur, however I am having problems getting this to work. Apparently I cant set it to float, does anyone know how i could fix this. This is how I was trying it out

1
2
3
4
 while (PokemonPowerLevel = !float) {
	cout << "Please enter the Pokemons power level: " << endl;
	cin >> PokemonPowerLevel;
	p->setPowerLevel(PokemonPowerLevel);
Maybe something like this?
1
2
3
4
5
while( true ) {
        cout << "Please enter the Pokemon's power level: ";
        if( cin >> PokemonPowerLevel ) break;
        cin.clear( ); cin.ignore( );
}
Formatted input uses as many characters from the stream as feasible and converts them to value of type. If no conversion is possible, then the stream rises a "fail" flag; all future read attempts will automatically fail, unless the error is cleared.

Thus, the
1
2
3
4
5
6
7
8
float foo;
std::cin >> foo; // 1
float bar;
std::cin >> bar; // 2
std::string gaz;
std::cin >> gaz; // 3
std::cin.clear(); // 4
std::cin.ignore( numeric_limits<streamsize>::max(), 'e' );

with input
42nd street

1. will assign 42 to foo and leaves "nd street" into the stream
2. fails to read anything into bar and leaves "nd street" into the stream
3. fails to read anything into gaz and leaves "nd street" into the stream
4. resets the flags of the stream. we can now try to read again
5. discards from stream everything up to first 'e', i.e. leaves "et" into the stream.

Furthermore:
1
2
3
4
5
6
float foo;
if ( std::cin >> foo ) {
  // read was successful; foo has a valid value
} else {
 // read failed; cin has fail-state
}

You need to #include <typeinfo> for this.

Checking if a value does not equal float:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <typeinfo>

int main()
{
    int x = 3, y = 5;
    float a = 3.14;

    if (typeid(x) != typeid(float))
        std::cout << "x is not type float\n\n";


    if (typeid(a) == typeid(float))
        std::cout << "a is type float\n";

    else
        std::cout << "a is not type float\n";

    std::cin.get();

    return 0;
}
Last edited on
[quoteMaybe something like this?
1
2
3
4
5
while( true ) {
cout << "Please enter the Pokemon's power level: ";
if( cin >> PokemonPowerLevel ) break;
cin.clear( ); cin.ignore( );
}][/quote]

This sort of works, it works in taking in the input, but when trying to read it back it messes it up.
So something along the lines of

while (typeid(PokemonPowerLevel) != typeid(float))
{
cout << "Please enter the Pokemons power level: " << endl;
cin >> PokemonPowerLevel;
p->setPowerLevel(PokemonPowerLevel);
}

should work?
This sort of works, it works in taking in the input, but when trying to read it back it messes it up.

Please explain.

So something along the lines of
while (typeid(PokemonPowerLevel) != typeid(float))

No. The type of PokemonPowerLevel is something that you do set explicitly when you declare that variable. The input event will not change the type.
Well when i give the input of the PokemonPowerLevel, it takes the input and moves onto the next question but when I call the function to read it back i get a random number, ie -4.31602e+ etc etc, but I placed in 10. I think its got something to do with the pointers.

To read back the info i use this function

1
2
3
4
5
6
7
8
void PrintPokemon() {
		for (vector<Pokemon>::iterator iter = CharacterPokemon.begin();
			iter != CharacterPokemon.end(); ++iter) {
			cout << "Your Pokemons name and type is -  Name: " << iter->getName() << ". Type: "<< iter->getType() << endl;
			cout << "Its power level is : " << iter->getPowerLevel() << endl;
			cout << iter->getName() << "'s weight and height are: " <<  iter->getWeight()  << "kgs, and " << iter->getHeight()  << " feet." << endl;
			}
	}


And this is the while loop i am trying to fix

1
2
3
4
5
6
while (true) {
		cout << "Please enter the Pokemon's power level: ";
		if (cin >> PokemonPowerLevel) break;
		p->setPowerLevel(PokemonPowerLevel);
		cin.clear(); cin.ignore();
	}
Could you explain each line of your while-loop?

(We know the answer already, but you have to learn to explain code.)
Well I am actually slightly confused with the loop (I actually made a reply earlier asking if someone could explain it a bit, but deleted when I noticed it wasnt working)

Anyway, from what I do understand is its looping while the condition is true, but this is where I got lost slightly cause to me there is no condition, ie if input = ! float repeat.

The cin in taking the input of the user and a pointer is assigning the input to PowerLevel which is done in the setPowerLevel.

There is a high chance I have used wrong terminology etc, ive only been learning c++ for about 3 months, so still not great with everything.

And I believe the cin.clear and ignore are used because of the white spacing before cin, (I only learnt this part today, so still not 100% about that)
When unsure, check the documentation. For example,
http://www.cplusplus.com/reference/istream/istream/ignore/
tells that cin.ignore(); actually does cin.ignore( 1, EOF );

In other words, that ignores the next character that is in the stream.


The true is always true. Therefore, the loop will loop forever?

Perhaps, the break jumps out of the loop. The break ends the loop.
When is the break called? Right after succesful input.

If so, when is the p->setPowerLevel(PokemonPowerLevel);? After the if-statement.
IF the input is successful, then the loop ends before setting powerlevel.
IF the input fails, then you update the powerlevel with invalid value.
Does that sound logical?

The clear() and ignore() clean up the stream somewhat (after failed input).


Perhaps you should set the powerlevel after the loop, when the input has succeeded and the PokemonPowerLevel thus has a valid number?
ok now that you explained the p->setPowerLevel(PokemonPowerLevel); I feel stupid. Sort of worries me that I wont be able to sort coding problems out by myself. Guess I just need to work harder.

Anyhow, thanks for the help. I really appreciate it.
Oh also if you are still around, i am still slightly confused that it knows that it needs to loop if its not a float that is entered. Does it just know that cause i declared Powerlevel as a float earlier.
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
http://www.cplusplus.com/reference/ios/ios/operator_bool/

Yes, you declare that the variable is a float. If the operator>> sees that whatever the user has written cannot be interpreted as a valid float value, then the operator sets the failbit of cin.

The operator >> returns the cin. Therefore,
1
2
3
4
5
 if ( cin >> foo )

// is like
cin >> foo;
if ( cin )

Topic archived. No new replies allowed.