String won't convert to negative float

Hi everyone. I'm trying to convert a string to a float but when I do it always goes positive. Right now someone types a string, and I check the first element for a negative but no matter what happens, it always turns it positive. What am I doing wrong?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  float getFloat(){
    string floatNumber;
    bool floatOk;
    float returnedFloat;
    do{
            cout<< "Enter a number: ";
            cin>>floatNumber;
            cout<<"You inputted: "<< floatNumber<<endl;
            floatOk = !(floatNumber.find_first_not_of( "-.0123456789" ) == std::string::npos);
            if(floatOk){
                cout<<"Invalid float number.  Please try again."<<endl;
            }
        }while(floatOk);
        if(floatNumber[0]=='-'){
            returnedFloat = stof(floatNumber);
            returnedFloat = -returnedFloat;
            return returnedFloat;
        } else {
            cout<<floatNumber[0]<<endl;
            return stof(floatNumber);
        }
}
Last edited on
It looks like you're telling it pretty clearly to always be positive.
1
2
3
4
5
6
7
8
        if(floatNumber[0]=='-'){
            returnedFloat = stof(floatNumber);
            returnedFloat = -returnedFloat;
            return returnedFloat;
        } else {
            cout<<floatNumber[0]<<endl;
            return stof(floatNumber);
        }

If it starts with - (minus), you are converting it to a float, and then negating it. Negating a negative becomes a positive.
if it doesn't start with -, then you aren't negating it.

Either way, the end result is positive.
> returnedFloat = stof(floatNumber);
> returnedFloat = -returnedFloat;
Maybe stof() already knows how to deal with the negative, so making it negative again on the 2nd line just makes it positive.

I tried taking out the extra code, now it looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
float getFloat(){
    string floatNumber;
    bool floatOk;
    float returnedFloat;
    do{
            cout<< "Enter a number: ";
            cin>>floatNumber;
            cout<<"You typed: "<< floatNumber<<endl;
            floatOk = !(floatNumber.find_first_not_of( "-.0123456789" ) == std::string::npos);
            if(floatOk){
                cout<<"Invalid float number.  Please try again."<<endl;
            }
        }while(floatOk);
        if(floatNumber[0]=='-'){
            returnedFloat = stof(floatNumber);
            //returnedFloat = -returnedFloat;
            return returnedFloat;
        } else {
            cout<<floatNumber[0]<<endl;
            return stof(floatNumber);
        }
}

it is still always returning a positive number.  In this case, I typed in -37.5 and it tells me that it's 37.5
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <sstream>
#include <string>
using namespace std;


template<typename T> T getVal()
{
   T val;
   bool OK = false;
   string str; 
   while( !OK )
   {
      cout << "Enter value: ";
      getline( cin, str ); 
      stringstream ss( str );
      OK = ( ss >> val && !( ss >> str ) );  // a T and nothing but a T
   }
   return val;
}


int main()
{
   float f = getVal<float>();
   cout << "You entered " << f << '\n';
}


Enter value: porcupine
Enter value: -37.5
You entered -37.5
Last edited on
Works for me.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
using namespace std;

float getFloat()
{
  string floatNumber;
  bool floatOk;
  float returnedFloat;
  do {
    cout << "Enter a number: ";
    cin >> floatNumber;
    cout << "You typed: " << floatNumber << endl;
    floatOk = !(floatNumber.find_first_not_of("-.0123456789") == std::string::npos);
    if (floatOk) {
      cout << "Invalid float number.  Please try again." << endl;
    }
  } while (floatOk);

  if (floatNumber[0] == '-') {
    returnedFloat = stof(floatNumber);
    //returnedFloat = -returnedFloat;
    return returnedFloat;
  } else {
    //cout << floatNumber[0] << endl;
    return stof(floatNumber);
  }
}

int main()
{
  cout << "In main, result=" << getFloat() << endl;
}


$ ./a.out 
Enter a number: -37.2
You typed: -37.2
In main, result=-37.2


Even in the debugger (a marvellous tool - learn how to use yours)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ g++ -g -std=c++11 baz.cpp
$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(gdb) b 20
Breakpoint 1 at 0x401055: file baz.cpp, line 20.
(gdb) run
Starting program: ./a.out 
Enter a number: -37.2
You typed: -37.2

Breakpoint 1, getFloat () at baz.cpp:20
20	  if (floatNumber[0] == '-') {
(gdb) p floatNumber 
$1 = "-37.2"
(gdb) n
21	    returnedFloat = stof(floatNumber);
(gdb) 
23	    return returnedFloat;
(gdb) p returnedFloat 
$2 = -37.2000008

Can you elaborate on how yours works lastchance and why mine doesn't? I'm trying to understand what I was doing wrong? Is there a way to fix mine to work? I basically need to ensure someone is typing in a float. FYI, I'm using an online c++ compiler, in this case the one at onlinegdb.com
Last edited on
@kruuth,
You haven't given a whole code, so it's difficult to tell. However, @salem c thinks your code works, so that is OK by me.

I have to say, your code is rather difficult to read. In particular,
- if you use stof() then it will automatically return the right sign; you don't have to do anything about minuses. You could simply use
return stof( str );
or you could simply input a float in the first place!
- most people looking at it would assume that floatOK goes true when all is OK; apparently, your code does the diametric opposite.
- similarly, most people would assume that floatNumber had type float; but in your code it has type string.


If you are using something online, particularly with a non-Windows PC, then it is just possible that what you think you are entering as a minus sign ... is actually some sort of hyphen.
Your code will accept "123-" or "1-234" or "1-800-222-1234". Let the library parse the number.
1
2
3
4
5
6
7
8
9
float f;
while (true) {
    cout >> "Enter a number: ";
    if (cin >> f) break;
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // That first argument is a really big number. Requires #include <limits>
    cout >> "Invalid number\n";
}

// When you get here, f is valid 



Last edited on
Actually you were spot on. I didn't realize I was printing the wrong value out. I had two variables, the pre and post value and I was printing pre on both cases.
Topic archived. No new replies allowed.