How to prevent fscanf from interpreting 0x2 as hex? - c

I have a file which stores values like 2.32x7.
I read the floating-point part using:
fscanf(file, "%lf", &value);
It works perfectly... except for when the file stores something like 0x2. In that case, it reads the entire string as a hexadecimal value.
How can I prevent this from happening?
I would like fscanf to just read 0 and ignore x2.
Edit:
As suggested by #dbush, I am adding a sample input file.
I am parsing polynomials. So, the input file will be something like:
0x2+2.32x7-4x-9
Runnable example.

For your purpose, you should read the full polynomial with fgets() and parse it with as hoc code using strtod() and strtol():
#include <errno.h>
#include <stdlib.h>
int parse_polynomial(struct polynomial *p, const char *s) {
for (;;) {
double factor = 1;
int exponent = 0;
char *p;
while (isspace((unsigned char)*s) {
s++;
}
if (*s == '\0')
break;
if (*s == '+') {
s++;
} else
if (*s == '-') {
factor = -1;
}
if (*s != 'x') {
errno = 0;
factor *= strtod(s, &p);
if (p == s || errno != 0) {
/* parse error */
break;
}
s = p;
}
if (*s == 'x') {
exponent = 1;
s += 1;
if (isdigit((unsigned char)*s) {
unsigned long ul;
errno = 0;
ul = strtoul(s, &p, 10);
if (p == s || errno != 0 || ul > INT_MAX)
break;
exponent = (int)ul;
s = p;
}
}
add_component(p, factor, exponent);
}
return (*s == '\0') ? 0 : -1;
}

Reading the line with fgets() and then parsing with crafted code is the most robust.
To read text as a single floating point number with fscanf() up to an 'x', first read with a scanset and then convert.
char buf[400 + 1]; // Something large - consider DBL_MAX may be 1e308
// Scanset of expected FP characters
#define FP_FMT " %400[-+.eE0-9]"
// or maybe simply
#define FP_FMT " %400[^x]"
if (fscanf(FP_FMT, buf) == 1 && sscanf(buf, "%lf", &value) == 1) {
// Success
Pedantic code would use strtod() instead of sscanf(buf, "%lf", &value).
Other consideration include locale use of ',' as the decimal point, NAN, infinity, even wider text as wee exact FP values, how to handle ill formatted text, input errors, EOF, ...
Consider scanning the pair of value and exponent in 1 step.
if (fscanf(FP_FMT "x%d, buf, &power) == 2 && sscanf(buf, "%lf", &value) == 1) {

❗❗❗ Incorrectly handles numbers with dots...
Thinking, how to fix that.
You can read the numeric characters, then parse number from the string: example
#include <stdio.h>
int main()
{
double value;
char s[32];
*s = 0;
scanf("%31[0-9]", s);
sscanf(s, "%lf", &value);
printf("%f\n", value);
scanf("%3s", s);
puts(s);
}
If you need negative numbers too: example
#include <stdio.h>
int main()
{
double value;
char s[32];
*s = 0;
scanf("%1[-+]", s);
scanf("%30[0-9]", s+!!*s);
sscanf(s, "%lf", &value);
printf("%f\n", value);
scanf("%3s", s);
puts(s);
}
Note that the last code eats the sign even if it's not followed by digits.

Related

Converting a char array for use with isdigit()

I've been trying to write out code that takes input from the user, stores it into a char array, and then identifies the input as a positive or negative integer, a positive or negative decimal, or a character string. So far this is the code I have.
void input() {
char userInput[500];
printf("Enter something: ");
fgets(userInput, 500, stdin);
for (int i = 0; i < strlen(userInput); i++) {
if (isdigit(userInput) == 0) {
printf("This is not a digit.\n");
}
}
}
I'm aware that trying to use a char array with isdigit() will not work. I'm having issues figuring out how to get around this. I'm assuming it would be possible to run through the array and identify what the input is. And I assume there is a way to cast the char array into an int so isdigit would work, but I'm a bit stumped. Any suggestions?
There seems to be some confusion between digit, which is a character between '0' and '9' and integer which is a number composed of such digits with an optional leading sign.
You can use isdigit() defined in <ctype.h> to check if a character is a digit, but testing if the string encodes a number is a different question.
Passing a char to isdigit() has undefined behavior is the char value is negative because isdigit() is only defined for a values of the type unsigned char and the special negative value EOF. To test if a char is a digit, you can write isdigit((unsigned char) userInput[i]).
To test if the string contains a number, you can use strtol(), and to test for a floating point value (which I assume you mean by decimal), you can use strtod().
You can also use sscanf(), which is probably easier for a simple program.
Here is a modified version:
#include <stdio.h>
void input() {
char userInput[500];
printf("Enter something: ");
if (fgets(userInput, sizeof(userInput), stdin)) {
int n;
double d;
char c;
/* try converting as an int,
test if the conversion succeeds
check that no trailing character is present.
sscanf returns the number of successful conversions
*/
if (sscanf(userInput, "%d %c", &n, &c) == 1) {
printf("string contains an integer %d\n", n);
} else
if (sscanf(userInput, "%lf %c", &d, &c) == 1) {
printf("string contains a double %g\n", d);
} else {
printf("string is an ordinary string: %s\n", userInput);
}
}
}
Note however that the above tests will accept leading and trailing whitespace and may invoke undefined behavior if the number cannot be represented in the target types.
You can use simple heuristics based on the character types to distinquish between integer, floating point, or string.
Introduce some new variables:
int slash = -1;
int digits = 0;
int chars = 0;
int decimals = 0;
int isNumber = 0;
int isNegative = 0;
int isFloat = 0;
int len;
Then your scanning code is this:
len = strlen(userInput);
for (int i = 0; i < len i++) {
if (userInput[i] == '-') {
slash = i;
}
else if (userInput[i] == '.') {
decimals++;
}
else if ((userInput[i] >= '0') && (userInput[i] <= '9')) {
digits++;
}
else {
chars++;
}
}
And then you can print the result as:
// NOT A NUMBER if:
// a dash anywhere but index 0
// more than one decimal
// no digits
// anything else that isn't a digit
isNumber = ( ((slash == -1) || (slash == 0)) &&
(decimals <= 1) &&
(digits > 0) &&
(chars == 0)
);
if (isNumber) {
isFloat = (decimals == 1);
isNegative = (slashPos == 0);
printf("string contains a %s %s: %s\n", (isNegative ? "negative" : "positive"), (isFloat ? "double" : "integer"), userInput);
}
else {
printf("string contains an ordinary string: %s\n", userInput);
}
}

Check if a number is an integer or not in C language

I want to check if a number given by a user is an integer or not in another way i want to verify if the input data is between −(2)^31= −2,147,483,648 and ((2)^31) - 1 =2,147,483,647
this is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int x;
int y = pow(3,31) * (-1);
int z = pow(3,32) - 1;
printf("\n\ty = %d et z = %d \n\n", y, z);
scanf("%d", &x);
if ((x < y) || (x > z)) {
printf("x is not an integer");
}
else {
printf("x is an integer");
}
return 0;
}
But while running the program the result always showing me x is integer even if x is greater than 2,147,483,647 or lesser than −2,147,483,648.
Testing whether input is a valid int decimal numeral or is a decimal numeral in [-231, 231) is actually a bit complicated. The C standard does not provide a direct way to do this. What we can do is:
Read characters and check to see whether they are in the expected form: spaces, an optional minus sign (hyphen), and digits. (Any non-digits after the digits will be allowed and ignored.)
Try using strtol to convert the numeral to a long. We use strtol because there is no C-standard library routine for converting to an int (or your fixed bounds using 231) that provides error indications.
Compare the long produced by strtol to the int bounds.
Example code for int bounds follows. If you want bounds of -2147483648 and 2147483647 instead, substitute those for INT_MIN and INT_MAX. To be completely safe, the code should actually use long long and strtoll, since the C standard does not require long to be able to represent −2147483648.
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// Prepare a buffer.
size_t BufferSize = 100, BufferUsed = 0;
char *Buffer = malloc(BufferSize * sizeof *Buffer);
// Skip white space.
int c;
do
c = getchar();
while (isspace(c));
if (c == EOF)
{
printf("Input is not an int: EOF before \"-\" or digit seen.\n");
exit(EXIT_SUCCESS);
}
// Accept a hyphen as a minus sign.
if (c == '-')
{
Buffer[BufferUsed++] = c;
c = getchar();
}
// Accept digits.
while (isdigit(c))
{
Buffer[BufferUsed++] = c;
if (BufferSize <= BufferUsed)
{
BufferSize *= 2;
printf("Realloc: size = %zu, used = %zu.\n", BufferSize, BufferUsed);
char *NewBuffer = realloc(Buffer, BufferSize * sizeof *NewBuffer);
if (!NewBuffer)
{
fprintf(stderr, "Error, unable to allocate %zu bytes.\n",
BufferSize);
exit(EXIT_FAILURE);
}
Buffer = NewBuffer;
}
c = getchar();
}
// Ensure we saw at least one digit (input is not blank or just a hyphen).
if (BufferUsed == 0 || BufferUsed == 1 && Buffer[0] == '-')
{
printf("Input is not an int: No digits present.\n");
exit(EXIT_SUCCESS);
}
// Put back the unaccepted character, if any.
if (c != EOF)
ungetc(c, stdin);
// Terminate the string.
Buffer[BufferUsed] = 0;
// Attempt to convert the numeral to long.
char *End;
errno = 0;
long x = strtol(Buffer, &End, 10);
// Test whether strtol succeeded.
if (*End)
{
/* I do not expect this to occur since we already tested the input
characters.
*/
printf("Input is not an int: strtol rejected %c.\n", *End);
exit(EXIT_SUCCESS);
}
if (errno == ERANGE)
{
printf("Input is not an int: strtol reported out of range.\n");
exit(EXIT_SUCCESS);
}
if (x < INT_MIN || INT_MAX < x)
{
printf("Input is not an int: Value is outside bounds.\n");
exit(EXIT_SUCCESS);
}
printf("Input is an int, %ld.\n", x);
free(Buffer);
}
Maybe i think i should store the number on a char array and check if it contains the float character '.'
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
int main(){
char number[10];
int flag=0,i = 0;
printf("\n\nEnter a number: ");
scanf("%s", number);
while(number[i++] != '\0'){
if(number[i] == '.'){
flag = 1;
break;}}
if(flag)
printf("\n\n\n\tyou Entered a Floating Number not an integer number\n\n");
else
printf("\n\n\n\t you Entered an integer Number\n\n");
return 0;}

How to get Integer and float input without `scanf()` in c?

How can I assign a integer and float values given by user to a variable or array without using scanf()?
Like we have getchar,fgetc,fgets...etc for char and string, Is there any function for floats and integers ?
There aren't functions to read integers and floats but you can use fgets with strtol for integers and strtof for floats:
// floats:
char str_f[20];
float f;
fgets (str_f, 20, stdin);
f = strtof(str_f, NULL);
// integers:
char str_i[20];
int i;
fgets(str_i, 20, stdin);
i = strtol(str_i, NULL, 0);
You can also use atoi for integers but it's not recommended because atoi doesn't detect errors and it's considered obsolete.
If you want to detect errors you can use the following code:
// floats:
char *endptr_f;
char str_f[20];
float f;
fgets (str_f, 20, stdin);
f = strtof(str_f, &endptr_f);
if (*endptr_f != '\n' || str_f[0] == '\n' || endptr_f == str_f)
{
printf("ERROR: \"%s\" is an invalid float!\n", str_f);
}
// integers:
char *endptr_i;
char str_i[20];
int i;
fgets(str_i, 20, stdin);
i = strtol(str_i, &endptr_i, 0);
if (*endptr_i != '\n' || str_i[0] == '\n' || endptr_i == str_i)
{
printf("ERROR: \"%s\" is an invalid integer!\n", str_i);
}
Years ago I wrote this, Tested in VS2017 and still works. Very simple, Not very good but maybe you can use it for something
#define INT_CONVERTED (1 << 0)
#define FLOAT_CONVERTED (1 << 1)
char *strlwr(char *str)
{
char *ptr = str;
while (*ptr)
{
*ptr = tolower(*ptr);
ptr++;
}
return str;
}
int NumberOfDots(char *s)
{
int dots = 0;
while (*s)
dots += *s++ == '.';
return dots;
}
int NOTstrcasechr(char *str, int ch)
{
return strchr(str, ch) == NULL && strchr(str, toupper(ch)) == NULL;
}
int ReadNumber(double *db, int *in)
{
int result = 0;
do
{
char str[100];
int dots;
result = 0;
printf("Enter number: ");
fgets(str, 100, stdin);
if ((dots = NumberOfDots(str)) > 1) str[0] = '\0';
if (sscanf(str, "%lf", db) == 1)
{
result |= FLOAT_CONVERTED;
}
if (!result || (!dots && NOTstrcasechr(str, 'e')))
if (NOTstrcasechr(str, 'x'))
{
if (sscanf(str, "%d", in) == 1)
{
result |= INT_CONVERTED;
}
}
else
if(result)
{
result |= INT_CONVERTED;
*in = (int)*db;
}
if (strstr(strlwr(str), "exit") != NULL) result = -1;
} while (!result);
return result;
}
int main(int argc, char **argv)
{
double db;
int in;
int result;
while ((result = ReadNumber(&db, &in)) != -1)
{
if (result & FLOAT_CONVERTED) printf("Float = %lf ", db);
if (result & INT_CONVERTED) printf("Integer = %d ", in);
printf("\n\r");
}
return 0;
}
Enter number: xfdsfdsfdsf
Enter number: rthdgfhghg
Enter number: 0x4567
Float = 17767.000000 Integer = 17767
Enter number: 3e67
Float = 30000000000000000978680950144401383192292617328216608963406365458432.000000
Enter number: 54567
Float = 54567.000000 Integer = 54567
Enter number: dfgdfgdfgdfgdgg
Enter number: 3456
Float = 3456.000000 Integer = 3456
Enter number: 12354654465454654654565567567576
Float = 12354654465454653961713368432640.000000 Integer = -1
Enter number: exit
Is there any function for floats and integers ?
Yes, it is scanf(), yet OP does not want to use that.
How to get Integer and float input without scanf()?
This is not a trivial task to do just like scanf("%d", &some_int), scanf("%f", &some_float).
The primary problem is to stop reading characters once the longest valid input is consumed - this could be in the middle of a line of user input. I did not find a terse robust solution.
Instead, talcked the problem of reading a line of user input for one integer long. Reading a float is similar. Changes needed near *** lines
Still the problem of finite text length occurs. The below code assumes valid input is made of up to 2x the maximum needed to print a long.
Overflow is an issue somewhat addressed here. Recall with scanf(), OF/UF is undefined behavior.
The central idea is to read a line by skipping whitespace, reading N characters and then looking for any non-white space after that. Then parse the buffer.
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// character array size needed to represent all `long`
#define INT_STR_SIZE (sizeof(long)*CHAR_BIT/3 + 3)
#define INT_BUF_SIZE (INT_STR_SIZE*2)
int readline_long(long *dest) { // ***
int ch;
while (isspace(ch = getchar()) && ch != '\n') {
;
}
if (ch == EOF) return EOF;
ungetc(ch, stdin);
char buf[INT_BUF_SIZE]; // ***
if (fgets(buf, sizeof buf, stdin) == NULL) return EOF;
if (strchr(buf, '\n') == NULL) {
// Get rest of line
bool only_white_space = true;
while ((ch = getchar()) != '\n' && ch != EOF) {
if (!isspace(ch)) only_white_space = false; // consume rest of line
}
if (!only_white_space) return 0; // extra junk
}
char *endptr;
errno = 0;
long y = strtol(buf, &endptr, 10); // ***
if (buf == endptr) return false; // no conversion
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (*endptr) return 0; // extra junk
*dest = y;
return 1;
}
Test code
int main(void) {
long lg;
int retval;
while ((retval = readline_long(&lg)) != EOF) {
printf("retval = %d", retval);
if (retval > 0) printf(" val = %ld", lg);
if (errno) printf(" errno = %d", errno);
putchar('\n');
fflush(stdout);
}
}

fetching string and converting to double

I'm trying to create a function which can determine if an input can be converted perfectly into a double and then be able to store it into an array of doubles. For example, an input of "12.3a" is invalid. From what I know, strtod can still convert it to 12.3 and the remaining will be stored to the pointer. In my function doubleable, it filters whether the input string consists only of digits. However, I'm aware that double has "." like in "12.3", and my function will return 'X' (invalid).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char doubleable (char unsure[], int length){
int i;
int flag;
for (i=0; i<length; i++ ){
if(isdigit(unsure[i]==0)){
printf("You have invalid input.\n");
flag=1;
break;
}
}
//check for '.' (?)
if(flag==1)
return 'X';
else
return 'A';
}
int main(){
char input [10];
double converted[5];
char *ptr;
int i;
for(i=0; i<5; i++){
fgets(input, 10, stdin);
//some code here to replace '\n' to '\0' in input
if(doubleable(input, strlen(input))=='X'){
break;
}
converted[i]=strtod(input, &ptr);
//printf("%lf", converted[i]);
}
return 0;
}
I'm thinking of something like checking for the occurrence of "." in input, and by how much (for inputs like 12.3.12, which can be considered invalid). Am I on the right track? or are there easier ways to get through this? I've also read about the strtok function, will it be helpful here? That function is still quite vague to me, though.
EDIT:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double HUGE_VAL= 1000000;
void string_cleaner (char *dirty){
int i=0;
while(1){
if (dirty[i]=='\n'){
dirty[i]='\0';
break;
}
i++;
}
}
int doubleable2(const char *str)
{
char *end_ptr;
double result;
result = strtod(str, &end_ptr);
if (result == HUGE_VAL || result == 0 && end_ptr == str)
return 0; // Could not be converted
if (end_ptr < str + strlen(str))
return 0; // Other input in the string after the number
return 1; // All of the string is part of the number
}
int main(){
char input [10];
double converted[10];
char *ptr;
int i;
for(i=0; i<5; i++){
while (1){
printf("Please enter:");
fgets(input, 10, stdin);
string_cleaner(input);
if (doubleable2(input)==0)
continue;
else if (doubleable2(input)==1)
break;
}
converted[i]=strtod(input, &ptr);
printf("%lf\n", converted[i]);
}
return 0;
}
thank you! It works just fine! I have a follow up question. If I enter a string that is too long, the program breaks. If I am to limit the input to, let's say, a maximum of 9 characters in input[], how am I to do that?
from what I understand about fgets(xx, size, stdin), it only gets up to size characters (including \n, \0), and then stores it to xx. In my program, I thought if I set it to 10, anything beyond 10 will not be considered. However, if I input a string that is too long, my program breaks.
You can indeed use strtod and check the returned value and the pointer given as the second argument:
int doubleable(const char *str)
{
const char *end_ptr;
double result;
result = strtod(str, &end_ptr);
if (result == HUGE_VAL || result == 0 && end_ptr == str)
return 0; // Could not be converted
if (end_ptr < str + strlen(str))
return 0; // Other input in the string after the number
return 1; // All of the string is part of the number
}
Note that you need to remove the newline that fgets most of the time adds to the string before calling this function.
From what I know, strtod can still convert it to 12.3 and the remaining will be stored to the pointer.
That is correct – see its man page:
If endptr is not NULL, a pointer to the character after the last character used in the conversion is stored in the location referenced by endptr.
So use that information!
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
bool doable (const char *buf)
{
char *endptr;
errno = 0;
if (!buf || (strtod (buf, &endptr) == 0 && errno))
return 0;
if (*endptr)
return 0;
return 1;
}
int main (void)
{
printf ("doable: %d\n", doable ("12.3"));
printf ("doable: %d\n", doable ("12.3a"));
printf ("doable: %d\n", doable ("abc"));
printf ("doable: %d\n", doable (NULL));
return 0;
}
results in
doable: 1
doable: 0
doable: 0
doable: 0
After accept answer
Using strtod() is the right approach, but it has some challenges
#include <ctype.h>
#include <stdlib.h>
int doubleable3(const char *str) {
if (str == NULL) {
return 0; // Test against NULL if desired.
}
char *end_ptr; // const char *end_ptr here is a problem in C for strtod()
double result = strtod(str, &end_ptr);
if (str == end_ptr) {
return 0; // No conversion
}
// Add this if code should accept trailing white-space like a \n
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (*end_ptr) {
return 0; // Text after the last converted character
}
// Result overflowed or maybe underflowed
// The underflow case is not defined to set errno - implementation defined.
// So let code accept all underflow cases
if (errno) {
if (fabs(result) == HUGE_VAL) {
return 0; // value too large
}
}
return 1; // Success
}
OP's code
No value with result == 0 in result == 0 && end_ptr == str. Simplify to end_ptr == str.
Instead of if (end_ptr < str + strlen(str)), a simple if (*end_ptr) is sufficient.
if (result == HUGE_VAL ... is a problem for 2 reasons. 1) When result == HUGE_VAL happens in 2 situations: A legitimate conversion and an overflow conversion. Need to test errno to tell the difference. 2) the test should be if (fabs(result) == HUGE_VAL ... to handle negative numbers.

C Getting decimal input from user issue

I'm trying to write a function to get a decimal input from the user and return the actual value converted from ASCII. However, the function causes the next input from the user to be skipped. As in:
Enter input: 123
Enter input: /* doesn; allow for input */
Enter input: 456
long sum = 0;
int character = fgetc(stdin);
while(character != '\n'){
if(character >= '0' && character <= '9'){
/* convert from ASCII */
character -= '0';
sum = sum * 10 + character;
}
else{
/* reenter number */
}
character = fgetc(stdin);
}
return sum;
To figure out why your code doesn't work, I suggest you post your full code, because problems may lie in the way you call this function.
So before full code is posted, I can just tell you that this code works well on my machine:
#include <stdio.h>
#include <ctype.h>
int getlong();
int main() {
printf("\t%d\n", getlong());
printf("\t%d\n", getlong());
return 0;
}
int getlong() {
long sum = 0;
int character = fgetc(stdin);
while (character != '\n') {
if (isdigit(character)) {
/* convert from ASCII */
character -= '0';
sum = sum * 10 + character;
character = fgetc(stdin);
}
else {
character = fgetc(stdin);
continue;
}
}
return sum;
}
ctype.h is included in order to use isdigit(), while tells you whether a character is decimal digit.
But in fact, you don't have to do everything on your own. Using standard library is more effective and efficient, both for you and for the computer.
For example, you can scan a long integer directly from stdin:
#include <stdio.h>
int main() {
long value;
puts("Please input numbers:");
while (scanf(" %ld", &value) != 1) {
puts("Only numbers are welcome:");
scanf("%*[^\n]");
}
printf("%ld", value);
return 0;
}
Notice the white-space at the beginning of format, this makes scanf() discard all white-space characters(including spaces, newline and tab characters) extracted until a non-white-space character is met.
Or, use strtol(), while is relatively rarely seen:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char buf[80];
char *pEnd;
long value;
do
{
puts("Numbers please:");
if (fgets(buf, 80, stdin) == NULL)
{
perror("fgets()");
return 1;
}
value = strtol(buf, &pEnd, 10);
}
while (*pEnd != '\n');
printf("%ld", value);
return 0;
}
Of course, sscanf() also works, you can just write the code on your own.
From comments:
an extra newline in the stdin buffer...
Try replacing your current method with scanf() using following format string:
char* fmt = "%[^\n]%*c";
It reads everything up to the newline, then consumes the newline. * is an assignment suppressor.
Example: (includes functions to convert input string to float/integer number)
float get_float(void);
long get_int(void);
int main(void)
{
float num_f = get_float();
long num_i = get_int();
return 0;
}
float get_float(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter floating point number and hit return:\n");
scanf(fmt, input);
return strtod(input, dummy);
}
long get_int(void)
{
char input[80];
char **dummy={0};
char* fmt = "%[^\n]%*c";
printf("Enter integer number and hit return:\n");
scanf(fmt, input);
return strtol(input, dummy, 10);
}
Note: These functions are bare bones illustrations of how converting input into number variables might be done, and were written without any error or range checking. As the commenter has stated, it would be worth your while before implementing production versions to read up on strtol() and strtof in detail. (Links are to the Linux man pages, but because both functions are part of the C standard libraries, documentation can also be found on MSDN here and here)
Why not just use fgets and sscanf?
char buf[80];
float n;
if (fgets(buf, 80, stdin) != NULL) {
if (sscanf(buf, "%f", &n) == 1)
printf("%f\n", n);
else
fprintf(stderr, "invalid float\n");
}

Resources