C++ Isfloat Function

C++ IsFloat function

If you can't use a Boost library function, you can write your own isFloat function like this.

#include <string>
#include <sstream>

bool isFloat( string myString ) {
std::istringstream iss(myString);
float f;
iss >> noskipws >> f; // noskipws considers leading whitespace invalid
// Check the entire string was consumed and if either failbit or badbit is set
return iss.eof() && !iss.fail();
}

Is there a way to check if a string can be a float in C?

The first answer should work if you combine it with %n, which is the number of characters read:

int len;
float ignore;
char *str = "5.23.fkdj";
int ret = sscanf(str, "%f %n", &ignore, &len);
printf("%d", ret==1 && !str[len]);

!str[len] expression will be false if the string contains characters not included in the float. Also note space after %f to address trailing spaces.

Demo

How to Check if input is float in C

The standard input is buffered. Anything that is given as input is first placed in a buffer from where the functions take them.

For example, when you give 3.14 as input, it is first placed in the buffer from where the scanf("%f") reads it.

When you give a non-float value, the scanf() didn't find the %f it expected. So it leaves the input in the input buffer itself and the next statement of the program is executed which happens to be another scanf() expecting %f. The input which was not consumed by the previous scanf() is still there in the input buffer and this is what the next scanf() uses. Again, the value is left unconsumed.

What you got to do is to somehow consume the non-float value in the input buffer after each failed read.

You could do something like

int ch;
while( (ch=getchar())!='\n' && ch!=EOF );

to consume from the input buffer till a newline. The newline would've been given when the user presses the Enter key.

scanf() returns the number of variables to which values were successfully assigned. This value should be 1 in this case for a successful read.

char ch;
while(scanf("%f", &subject[i].units)!=1){
printf("Invalid input. Re-enter units again: \n");
while( (ch=getchar())!='\n' && ch!=EOF );
}

You can do away with the second scanf().

C - How to check if the number is integer or float?

I would suggest the following:

  1. Read the number into a floating point variable, val, say.
  2. Put the integer part of val into an int variable, truncated, say.
  3. Check whether or not val and truncated are equal.

The function might look like this:

bool isInteger(double val)
{
int truncated = (int)val;
return (val == truncated);
}

You will likely want to add some sanity checking in case val is outside the range of values that can be stored in an int.

Note that I am assuming that you want to use a mathematician's definition for an integer. For example, this code would regard "0.0" as specifying an integer.

Is it possible to test a float using isdigit() function?

isDigit() only takes a character input.
The best way to check that you are getting input correctly is to use

if(scanf("%f", &userNum) != 1) {
// Handle item not float here
}

Since scanf() will return the number of items correctly scanned.

Checking if float is an integer

Apart from the fine answers already given, you can also use ceilf(f) == f or floorf(f) == f. Both expressions return true if f is an integer. They also returnfalse for NaNs (NaNs always compare unequal) and true for ±infinity, and don't have the problem with overflowing the integer type used to hold the truncated result, because floorf()/ceilf() return floats.

Is this a bad way to check if a string represents a floating point number?

For 999 digits and one point, there are 1000 recursive calls with each return address, and three parameters on the stack. I would find that okay. However a non-recursive iterative solution does away with the state parameters, and is easier to read (in this case only).

bool isFloatString(char *s)
{
int pointCounter = 0;
bool digitAfterPoint = false;
while (*s != '\0')
{
if (isdigit(*s))
digitAfterPoint = pointCounter == 1;
}
else if (*s == '.' && pointCounter == 0)
{
++pointCounter;
}
else
{
return false;
}
++s;
}
return digitAfterPoint;
}

Mind: the recursive solution is subject to a malicious stack overflow.


@MatteoItalia rightly indicated that there is only tail recursion (nothing is done with the result), so any mature C/C++ compiler would transform the recursion to jumps (iteration). Here his disassembly (see link in comment too).

isFloatString(char*, int, bool):
movsx ecx, BYTE PTR [rdi]
mov r9d, edx
mov r8d, ecx
sub ecx, 48
cmp ecx, 9
jbe .L23
cmp r8b, 46
je .L24
test r8b, r8b
sete al
and eax, edx
ret
.L24:
xor eax, eax
test esi, esi
je .L25
.L1:
rep ret
.L23:
movsx eax, BYTE PTR [rdi+1]
mov ecx, eax
sub eax, 48
cmp esi, 1
je .L26
cmp eax, 9
movzx edx, dl
jbe .L10
cmp cl, 46
je .L27
.L8:
test cl, cl
sete al
and eax, r9d
ret
.L26:
cmp eax, 9
jbe .L28
xor eax, eax
cmp cl, 46
mov r9d, 1
jne .L8
jmp .L1
.L28:
mov edx, 1
.L10:
add rdi, 2
jmp isFloatString(char*, int, bool)
.L25:
movzx edx, dl
add rdi, 1
mov esi, 1
jmp isFloatString(char*, int, bool)
.L27:
xor eax, eax
test esi, esi
jne .L1
add rdi, 2
mov esi, 1
jmp isFloatString(char*, int, bool)

How do I check that a number is float or integer?

check for a remainder when dividing by 1:

function isInt(n) {
return n % 1 === 0;
}

If you don't know that the argument is a number you need two tests:

function isInt(n){
return Number(n) === n && n % 1 === 0;
}

function isFloat(n){
return Number(n) === n && n % 1 !== 0;
}

Update 2019
5 years after this answer was written, a solution was standardized in ECMA Script 2015. That solution is covered in this answer.



Related Topics



Leave a reply



Submit