1

I'm writing a program in C, and one of the requirements is that the user input a number as a string value, and then the program must convert it to floating point format, and then do various things to that value. I can't seem to figure out how to simply convert the input string into a number. How would I write the first chunk of code like that? I know there are posts similar to this, but they haven't been helpful. I need to do this fairly simply, and I'd like to not have to #include anything besides ...

#include <stdio.h>

int main(int argc,char* argv[]) { 
  /*having issues with this in particular...*/

  int number;    
  int newNumber;
  int i;
  printf("Enter a number in decimal...");
  scanf("%d",&number);

  /*                        */

  printf("%d in binary is: ",number);
  for(i = 31;i >= 0;i--) {
    newNumber = (number>>i);
    if(newNumber & 1) {
      printf("1");
    }
    else {
  printf("0");
}
   }  


  return 0;
}

Thanks!

5
  • There is no relationship between code and question !!!. Commented Feb 26, 2014 at 2:16
  • What is the issue you are having, you already have scanf("%d"…) which does convert the input string to a number? Commented Feb 26, 2014 at 2:17
  • Your code appears to "work" - in that it reads the input and produces output. You might consider adding \n at the end of your printf statements. What exactly isn't working for you? Consider using 8*sizeof(int)-1 rather than 31. You don't know ahead of time how big an int is on your system. Commented Feb 26, 2014 at 2:18
  • Based on the answers you have received so far, it seems to me that maybe you need to explain your "problem" more clearly. What exactly is it that isn't working for you in the above code? "Having issues" is a bit vague. Perhaps you can edit your question: "when I input xxx I would like yyy but instead zzz". Commented Feb 26, 2014 at 2:43
  • What i was saying was that i need the input from the user to be of a 'string' type, and then i needed to convert it to 'float' type. So for example "int number" would become "char[100] number". Commented Feb 26, 2014 at 2:51

4 Answers 4

2

Following up on the comment I made:

Your code appears to "work" - in that it reads the input and produces output. You might consider adding \n at the end of your printf statements. What exactly isn't working for you? Consider using 8*sizeof(int)-1 rather than 31. You don't know ahead of time how big an int is on your system.

With a tiny change your code works very nicely for me:

#include <stdio.h>

int main(int argc,char* argv[]) {
  /*having issues with this in particular...*/

  int number;
  int newNumber;
  int i;
  printf("Enter a number in decimal...\n"); // <<< added a newline
  scanf("%d",&number);

  /*                        */

  printf("%d in binary is: ",number);
  for(i = sizeof(int)*8 - 1;i >= 0;i--) {  // make sure `i` starts with the right size
    newNumber = (number>>i);
    if(newNumber & 1) {
      printf("1");
    }
    else {
      printf("0");
    }

  }

  printf("\n");  // <<< print a newline

  return 0;
}

When I run it:

Enter a number in decimal...
123
123 in binary is: 00000000000000000000000001111011

note - you do have to input an integer for this to work. If you need your code to be more robust to user "error" in the input, your best bet is to read the input as a string, then do some more parsing. For example:

char buffer[100];
printf("enter an integer:\n");
fgets(buffer, 100, stdin);
// now you can look for spaces, letters, anything you want to skip, in the string
// you could even use sscanf().
// scanf() is a terribly fragile function to use, especially with "free form user input".
if(sscanf(buffer, "%d", &number) == 1) {
  // successfully converted number... run your code
} else {
  printf("unable to convert input to a number!\n%s\n", buffer);
  return 0;
}

another note re-reading your question, you said "program has to convert to a floating point number. This means you should do

float fnumber;
sscanf(buffer, "%f", &fnumber);

or

double dnumber;
sscanf(buffer, "%lf", &dnumber);

to do the conversion. But then, if you want to print as a binary, you need to cast the number from floating point to unsigned integer - a bit shifting operation is not well defined for a floating point number. So

unsigned int *intPtr, number;
intPtr = (unsigned int*) *fnumber; // this is hairy but it works
number = *intPtr;

and now use number as before - you will be able to print out the binary equivalent of the floating point number. There are people who will complain that the above is not "true to the standard". They might prefer it if you created a union:

union f2i
{
  float fvalue;
  unsigned int ivalue;
} Values;

Then assign the input to Values.fvalue, and use Values.ivalue to print out the binary number. It is still a hack...

Sign up to request clarification or add additional context in comments.

3 Comments

I know it does work, but the assignment I was given specified that the user input needs to be a string...I know, it's picky
Please note that there is no way to safely recover from an error if the input is out of range of the argument when using scanf(), since out of range conversions results in undefined behavior (C.11 Section 7.21.6.2 paragraph 10).
@jhx - I completely agree with you. Hence my comment in the answer: // scanf() is a terribly fragile function to use, especially with "free form user input". You state it more explicitly, and give a reference. Thanks for that! I wish that scanf() and gets() would be taken out of the curriculum (and possibly the standard). Nothing but trouble.
2

You can use strtod(). Read the number into a buffer as a string (say with fgets()), and then do:

double x;
char *endptr;
errno = 0;
x = strtod(buffer, &endptr);
if (endptr == buffer) {
    //... parse error or empty input ...
} else if (*endptr != '\n' && *endptr != '\0') {
    //... parse error extraneous data ...
} else if ((x == HUGE_VAL || x == -HUGE_VAL) && errno != 0) {
    //... error overflow ...
} else if (x <= DBL_MIN && x >= -DBL_MIN) {
    if (errno != 0) {
        //... error underflow (detected) ....
    } else {
        // ... underflow still possible, but is undiagnosed ...
    }
}

Error checking is done by checking both the value returned for x, and if errno got set. Parse errors is done by checking the endptr. The C standard says underflow detection is implementation defined (C.11 §7.22.1.3 ¶10).

3 Comments

Upvoting for the solid approach to error checking. If the user can input garbage, they will - so you better make sure your code can cope.
Idea: If buffer has the value "\n", this code does not complain. I think char* endptr; x = strtod(buffer, &endptr); if (buffer == endptr) fail(); catches inputs that are all white-space or "".
You've well covered over/underflow issues! The implementation defined behavior of underflow is a muddy corner case -too bad. A pesky issue remains as to how big to make char buffer for fgets(). Likely situation dependent.
1

Simple scanf example tested with GCC 4.7.3

$ gcc -Wall -Wextra -pedantic -std=c99 cstring-double.c

#include <stdio.h>

int main() {
  double v;
  int err;

  err = scanf("%lf", &v);
  if (1 == err) {
    printf("%lf\n", v);
  } else {
    printf("read failed\n"); }

  return 0; }

1 Comment

Please note that there is no way to safely recover from an error if the input is out of range of the argument when using scanf(), since out of range conversions results in undefined behavior (C.11 Section 7.21.6.2 paragraph 10).
0

Just use atof. cplusplus documentation

5 Comments

Don't use atof(), strtod() should be used instead.
Totally subjective, and there are no absolutes in coding. strtod() is surely safer, but atof() is still a correct answer to his question... I did add the documentation if you didn't notice.
I agree that this is a valid answer, so +1 from me. But, note that atof() does not report back any errors.
From the question: " I'd like to not have to #include anything besides ..." - and atof() needs #include <stdlib.h>. So it is not optimal. Not enough for me to downvote - but not optimal.
@Floris: For that part of the requirement, the only safe option is to implement strtod() using only the functions available in <stdio.h>, which is even less optimal.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.