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?

Recommended Answers

All 41 Replies

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.

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.

>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.

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); .

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.

Member Avatar for iamthwee

I agree with dave's tutorial.

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.

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?

This is code:

#include<stdio.h>
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

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.

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.

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.

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.)

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?

This is the real line by the way:

if ( fgets(text, sizeof text, stdin) )
   {

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?

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'.

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.

Member Avatar for iamthwee

@server_crash try devshed? But I thought u were already using that. :rolleyes:

Well done Dave.
I don't know for sscanf function and I just want to help server crush to solve problem. This pice of code that I send in last reply I wrote for program that calculate postfix formula value that enter as string and it works perfectly.
Your solution is much better than mine.
About void main ():
You probably know that main is function that is call by operating system and it don't have to return any value like any other function. It also don't have to take any parametars. If you write int main() the operating system expect to main return an integer (for exemple code of error) but in this program there is no need for this.
Sory if I don't understand you or you don't understand me.
That is because my English is very bad,because I am from Serbia.

This pice of code that I send in last reply I wrote for program that calculate postfix formula value that enter as string and it works perfectly.
Your solution is much better than mine.

Hopefully you've got the rest of it somewhere.
And hopefully you realize that there might be other characters that a part of a valid number.
And hopefully it doesn't leak memory like it looks like it does.
And hopefully you'll use simpler notation some day. And hopefully you can one day strip out all the inefficiencies.
And hopefully you do actually #include the proper headers.

About void main ():
You probably know that main is function that is call by operating system and it don't have to return any value like any other function. It also don't have to take any parametars. If you write int main() the operating system expect to main return an integer (for exemple code of error) but in this program there is no need for this.

Yes, the OS does already expect a return value, and not providing one is not a good thing.
http://c-faq.com/decl/main.html

>You probably know that main is function that is call by operating system
That's news to me. I was under the impression that the C runtime startup code calls main. But you clearly have a command of C that surpasses mine, so who am I to argue? :rolleyes:

>and it don't have to return any value like any other function
Wrong, and I shudder to think where you got that impression from.

>It also don't have to take any parametars.
True, but irrelevant to the topic of return values.

>but in this program there is no need for this
Also wrong. Let's assume, for the sake of argument, that your runtime startup code does this:

exit ( main ( argc, argv ) );

When you define main as returning void, assuming it even manages to run for reasons that you're probably not aware, what value is passed to exit? If you said "I dunno", you get a cookie. The value is undefined, the behavior is undefined, and undefined behavior is about the worst bug you could ever have. Now imagine trying to debug a crash at this level.

About void main ():

In addition, check out this

@server_crash try devshed? But I thought u were already using that. :rolleyes:

I am, but there's specific reasons why I was wanting to compile and run under Miracle C.

Is there a reason why the fgets is delimiting a '.'? If I enter 5.5 it truncates to 5... How can I get around this?

> but there's specific reasons why I was wanting to compile and run under Miracle C.
Because you're a masochist?
Like Dave said, Miracle C is a silly PoS compiler which looks great if your homework was "write a C compiler", but is utterly useless for anything more complicated than "hello world". Even crusty old TurboC had more features, and dev-c++ just wipes the floor with it. The bonus round is that dev-c++ is really $0 whereas Miracle C is $$$ nagware. Perhaps the real miracle is that people actually pay for that junk.

The only thing you will learn is frustration, and there's plenty of that coming your way even with a decent compiler.

If it's your school telling you to use that crud, then find a better school because they'll be incapable of teaching you anything useful.

Because you're a masochist?

I suggest you shut your big yapper [insert Moderator's profanity edit here]

If it's your school telling you to use that crud, then find a better school because they'll be incapable of teaching you anything useful.

Schools out tard. Java is the only thing taught at my school (when it's actually going on).

Is there a reason why the fgets is delimiting a '.'? If I enter 5.5 it truncates to 5... How can I get around this?

Not according to the specification. It should stop only at a Newline or EOF character.

Reads characters from stream and stores them in string until (num -1) characters have been read or a newline or EOF character is reached, whichever comes first.

How do you know that it is reading only 5? Are you using a debugger or using printf? If you are using printf maybe you are using a wrong format specifier.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.