Question:
C Programming: scanf("%d", a) Error With "Characters"?
anonymous
2010-09-12 20:26:05 UTC
include

int main(void)
{

int a, b;

printf("Enter Value:");
scanf("%d", &a);

printf("\n\nEnter Value:");
scanf("%d", &b);

}
Four answers:
husoski
2010-09-12 21:37:25 UTC
scanf() isn't all that easy to use properly and recover from invalid input.



I use a combination of fgets() and sscanf() to do a bulletproof scan of a single number for a single prompt. Something like this:



int GetInt(char *prompt, int *result)

{

... char ans[64];

... int len, nconverted, value;

... char extra;

... fputs(prompt, stdout);

... if (fgets(ans, sizeof ans, stdin) == NULL)

... ... return 0;

... len = strlen(ans);

... if (len == (sizeof ans - 1) && ans[len-1] != '\n')

... ... return 0;

... nconverted = sscanf(ans, " %d %c", &value, &extra);

... if (nconverted != 1)

... ... return 0;

... *result = value;

... return 1;

}



The arguments are a prompt string and a pointer to where to store the result.



The return value is a logical true (nonzero) if the number parsed correctly, or false (0) if there was any error. On an error return, no change was made to the (*result) value.



That was typed from memory, so there may be errors. The idea is to get the whole response line into a buffer, using fgets() -- NEVER use gets() ever ever ever -- to guard against too much input. If the buffer is full and doesn't end with a \n newline, then an error is returned. (You may have to increase the buffer size if you run on a 256-bit computer. :^)



Next, sscanf is used to scan from that response string. The format " %d %c" has four elements. The first space skips 0 or more spaces and/or tabs, the %d attempts to parse and convert an integer, the second space skips 0 or more spaces/tabs again, and finally--if there are any characters left--%c stores the first such character into (extra). That store into extra should never happen, and the return value from sscanf() tells how many fields were stored. If the return value is 1, then only the integer was stored. Any other value indicates an error. (0 values stored means that no number was found, 2 values stored means that a number was found, but it was followed by unwanted garbage.



Finally, only if all went well does the function actually store the parsed value into *result.



You can see why I make this a function. I don't want to be coding this at every input.



A really simple calling sequence might be:



while (!GetInt("Tell me your age: ", &age) || age < 1 )

{

... printf("That's not a good age!\n");

}



Put the GetInt function before main(), and you won't need a prototype. Otherwise, you'll need to add:



int GetInt(char *prompt, int *result);



...at the top of your file. You'll need #includes for and up there, no matter what.



Edit: At least two errors. I coded "null" instead of "NULL" for the fgets() error test. Too much Java or not enough mocha java, I guess. Also, I misspelled "value" as "val" in two spots. This version should at least compile...
Ratchetr
2010-09-12 20:41:54 UTC
Have to disagree with the answer that says this is bad programming because the program blows up if the user enters X.



scanf returns a value, and you should always check that return value. The value is the number of items converted.



You should write the code something like this:

int a;

int res = 0;



while(res != 1)

{

 printf("Enter Value:");

 res = scanf("%d", &a);

}



When you code it this way, it will usually be safer than reading in a string. It's very easy to create a buffer overflow vulnerability using string "%s" input if you aren't careful.



I'm not sure that really answers your original question, it was a bit vague just when you are seeing an error.



ETA: Thanks to Husoski for pointing out that the solution I posted doesn't actually work :-(



The correct code (need to flush the buffer) would be:



while(res != 1)

{

  printf("enter number");

  res = scanf("%d",&a);

  scanf("%*[^\n]"); // Flush

}
anonymous
2010-09-12 20:29:54 UTC
Bad programming. If the user types x, the program blows up. (x isn't an integer.) Input characters or strings. If they're numeric, convert to the numeric variable. If not, pop an error message to the user.
anonymous
2016-10-26 08:22:48 UTC
I managed to get it operating...what I did replaced into I further a sparkling variable (referred to as avg1) and gave your function a go back fee (if a function isn't void it needs to go back something), and renamed all references to avg to avg1. the reason why you've been getting that mistakes replaced into because (the computer thinks) you've been tiring to preform an mixture (an operation that addresses the function as one merchandise) operation, which isn't allowed in C++ except you carry out a touch kind of overloading, regardless please take a check out my answer and study from it. better of success contained in the programming international, its incredibly thrilling!!! #contain iostream #contain making use of namespace std; double avg (double a, double b, double c,double avg1); int important () { double a, b, c,avg1; avg(a,b,c,avg1); cout<<"enter a spread it is larger than 0:"; cin>>a; cout<<"enter yet another variety better than 0:"; cin>>b; cout<<"enter the perfect variety:"; cin>>c; cout<<"the perfect of the three numbers is:"; cout<> z; go back 0; } double avg (double a, double b, double c,double avg1) { avg1=(a+b+c)/3; go back 0; }


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...