954,496 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

[C] scanf

I have the following simple piece of code:

double new_amount;
     printf("Enter an amount: ");
     scanf ("%d", &new_amount);


For some reason, it always give me zero as the new_amount no matter what I input.

What exactly am I doing wrong?


Also, is there a way I can do a little bit of error trapping in C like try-catch or maybe even just test whether the input IS numeric?

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

It's a type mismatch. %d expects a pointer to int, but you give it a pointer to double.

>just test whether the input IS numeric?
If scanf returns a certain value, it failed. Your documentation will tell you what values mean what failures.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 
If scanf returns a certain value, it failed. Your documentation will tell you what values mean what failures.

As you may know,scanf returns the number of items stored from the stream, and EOF only if the EOF character was read at the beginning. So when you input 123.asdf for a double value, scanf will store 123 as the value but not return a unique error value. In this case the return value will be 1 because it stored one value from the stream. This is not a error checkable return error. Is there anyway to get over this? I think that was what server crash was looking for.

WolfPack
Postaholic
Moderator
2,051 posts since Jun 2005
Reputation Points: 572
Solved Threads: 115
 

My usual advice: avoid scanf : User Input: Strings and Numbers [C]
(And in the snippets links, I do show some things, such as this .)

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

>Is there anyway to get over this?
Yes, use fgets or something similar to read an entire line. Then error check it and finally parse it with sscanf. That would be one of the cases where scanf is being used for something other that it was designed for and the effect is detrimental to the robustness of the code.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

In your scanf() function your need to enter an float value, but you convert it to integer. Tru to write scanf ("%f",&new_amount); insted
scnaf("%f",&new_amount); .

brale
Newbie Poster
21 posts since Jun 2006
Reputation Points: 10
Solved Threads: 0
 
In your scanf() function your need to enter an float value, but you convert it to integer. Tru to write scanf ("%f",&new_amount); insted scnaf("%f",&new_amount); .

If you'll notice, it was a double -- not a float -- so your format specifier is not correct.

But why don't you follow the advice in this thread as well.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

I agree with dave's tutorial.

iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
 

Dave,
as you know DOUBLE and FLOAT are type for real numbers.
Conversion for FLOAT is %f and for DOUBLE is %lf.
If we use %f real number can have only 6 decimals so if we input
2.71565485654 the program will convert it to 2.715654 and if we use
%lf the program will accept whole number.
So the final solution for this problem is:
scanf("%lf",&new_amount);
Try with this and you will see that it works perfectly.

brale
Newbie Poster
21 posts since Jun 2006
Reputation Points: 10
Solved Threads: 0
 

Try to understand what is asked in the original post.
Also, is there a way I can do a little bit of error trapping in C like try-catch or maybe even just test whether the input IS numeric?So now let's try your solution.

four
Enter an amount: new_amount = 2.12409e-314


Do you get it yet?

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

This is code:

#include
void main () {
double new_amount;
printf("Enter an amount: ");
scanf ("%lf", &new_amount);
printf("%lf",new_amount);
}

Try with this and you will see that it works.

Enter an amount: 2.2565458745
2.2565458745

brale
Newbie Poster
21 posts since Jun 2006
Reputation Points: 10
Solved Threads: 0
 

And about the second question:
You can made your own function to test the nature of input.
For exemple:

int isnumber (char a) {
      if (a=='0' || a=='1' || a=='2' || a=='3' || a=='4' || a=='5' || a=='6' || a=='7' || a=='8' || a=='9') return 1;
      return 0;
 }
 
 int number (char a) {
	  if (a=='0') return 0;
	  if (a=='1') return 1;
	  if (a=='2') return 2;
	  if (a=='3') return 3;
	  if (a=='4') return 4;
	  if (a=='5') return 5;
	  if (a=='6') return 6;
	  if (a=='7') return 7;
	  if (a=='8') return 8;
	  if (a=='9') return 9;
 }

double numvalue (char *p,int *error) {   //This is a test function
      char *ceodeo,*razdeo;
      int OK=1,ERROR=0;
	  int pamtij,j=0,k=0;
	  double ceo=0,raz=0;
      while (isnumber(*(p+j))) {
		  j++;
	  }
	  ceodeo=malloc((j+1)*sizeof(char));
	  for (k=0;k<j;k++) {
	      *(ceodeo+k)=*(p+k);
	  }
	  *(ceodeo+j)=0;
	  if (*(p+j)=='.') {
	     j=0;
		 while (isnumber(*(p+pamtij+1+j))) {
		       j++;
		 }
	     razdeo=malloc(sizeof(char)*(j+1));
         for (k=0;k<j;k++) {
	      *(razdeo+k)=*(p+pamtij+1+k);
		 }
         *(razdeo+j)=0;
		 pamtij+=j;
		 goto racun;
	  }
	  if (*(p+j)==' ' || *(p+j)==0) {
	     razdeo=malloc(sizeof(char));
		 *razdeo=0;
	  }
      racun:;
	  for (k=0;k<strlen(ceodeo);k++) {
		  ceo+=broj(*(ceodeo+strlen(ceodeo)-1-k))*pow(10,k);
	  }
	  for (k=0;k<strlen(razdeo);k++) {
		  raz+=broj(*(razdeo+k))*pow(10,-k-1);
	  }
	  if (j!=strlen(p)) *error= ERROR;
                  else *error=OK;
                  return ceo+raz;
          }

program:

#include<stdio.h>
#include<string.h>

// There you have to write declarations of those 3 functions 
void main () {
   char input[30];
   double new_amount;
   int error;
   printf("Enter an amount: ");
   gets(input);
   new_amount=numvalue (input,&error);
   if (error==1) printf("New amount is: %lf",new_amount);
   else printf("You didn't enter a number!");
}

In this program you enter a string insted of double so you can test it is it a number or not.

brale
Newbie Poster
21 posts since Jun 2006
Reputation Points: 10
Solved Threads: 0
 

Wow, brale, that code is awful. But rather than hurt your feelings, I'll let someone else tell you all of the things that are wrong with it.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 
This is code:

These are code tags : [code][/code].

void main () {


main returns an int .

printf("Enter an amount: ");


If you want to ensure that the prompt be printed, try adding fflush(stdout); . http://c-faq.com/stdio/fflush.html

printf("%lf",new_amount);


%lf is undefined behavior in C90, but the l is ignored in C99.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 
And about the second question: You can made your own function to test the nature of input. For exemple:

Hmm. If that mess actually did compile, would it handle all characters that could be valid for a double ?

Hey, I've got an idea! Keep ignoring this!(And in the snippets links, I do show some things, such as this .)I wouldn't want to take those 2 or 3 lines of code that handle things better than your code, I'd much rather wade through your incomplete mess. (If only you could understand how awful it is.)

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

Thanks for all the replies.

To Dave: I loved the way your tutorial was dealing with input, but Miracle C is giving me the following error on the fgets line:

Parse Error, expecting `'('' 'if ( fgets(text, sizeof text, (&_files[0])) ) { int num' aborting compile

Do you have any idea why it's saying that?

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

This is the real line by the way:

if ( fgets(text, sizeof text, stdin) )
   {
server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

To Dave: I loved the way your tutorial was dealing with input, but Miracle C is giving me the following error on the fgets line:

Do you have any idea why it's saying that?

Maybe because Micracle C is a POS toy that is not intended to be a real compiler?

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

Wow, it turned out that it couldn't comprehend this line:

sizeof text because parenthesis weren't there: sizeof(text)

Then, it's adhering to the age old standard of variables need to be declared before the 'block'.

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

No, this is just one of many places it fails to implement the language.The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You