-
scanf problem
Hi all,
I have a problem but im not quite sure how to get over it. I will list these below:
1) Im scanning an input from the keyboard and i want to check that it is not in a certain range on the ASCII table, but when i use scanf it does not work?? I tried using getchar, but the maths of my program functions goes crazy? Please could you advise me on how i can change my if statement so it works.
Look forward to your advice
Tuurbo46
-
First of all, instead of posting your (short) code as an attachment, post it inline with code-tags. It makes it easier to see (don't have to click again, which makes the likelyhood of an answer better).
Code:
char c = 0;
scanf("%d", &c);
if((c==32)||(c<48)||(c>57)) // ASCII table
{
printf("Invalid input\n");
}
The %d format is for reading integers, your data is a char. That will lead to some "undefined behaviour", which is a bad thing. For one thing, it will overwrite whatever is after teh char variable with the remaining bytes to the sizeof(int) [usually 4 - so 3 bytes of "overwritten data"].
You should use %c for reading chars. Or use getchar().
Second, it is redundant to check if your input is "space" (32) or less than 48 - since the former is true when the latter is true.
I would also prefer to see
Code:
if (c < '0' || c > '9')
...
It saves someone who isn't perfectly up to date with the ascii table to understand what is being checked, as well as making it portable to machines that doesn't specifically use the ASCII character set [this is less of an issue on modern systems, as EBCDIC and other non-ASCII character sets are fairly rare nowadays].
--
Mats
-
Code:
char c = 0;
scanf("%d", &c);
if((c==32)||(c<48)||(c>57)) // ASCII table
{
printf("Invalid input\n");
}
First off wheres your main function?
To get a character with scanf you want to do: scanf("%c", &c);
Or better yet; maybe use getchar() to get the character.
Also if this part: (c==32) is redundant as 32 is less than 48.
Edit: too late :(
-
-
Quote:
Originally Posted by
zacs7
why not use isprint() ?
You mean "isdigit()" I suppose? :)
--
Mats
-
Hi,
Thanks for your help. Such silly mistakes on my part, but important lessons.
Also thanks for the advise on the ASCII trick.
Cheers Tuurbo46
-
Hi again,
Sorry, i have just seen all the other posts;
1) i used scanf, because this is what i have used before. Is isprint(), or isdigit() better?
2) I did not include main, because i just added a snap shot to keep it simple.
-
isprint(), isdigit() an dother "is" functions take a character as an argument [1], and tell you if the argument "is a digit" or "is a printable character" [so, it's not a control character for example]. There are about 10 or so different functions that do similar things. It still means that you need to use getchar() or some such to read the character in.
The "is" functions are excellent for checking if your input "is valid" - if it's a digit, an alpha, alphanumeric, hex digit, etc, etc. They also work on "any character set".
[1] Technically, the function allows an integer as input - this is so that it's safe to use this funciton on EOF [which is -1]. However, for all intents and purposes, see the input as a char.
--
Mats
-
>You mean "isdigit()" I suppose?
Yes... my bad. At least you got the point, and in the end that's all that really matters eh? :p
Just trying to justify my error :)
-
Hi again,
After your help, the previous problem is cured, and now i have another problem:
1) Scanf has to accept both numbers and letter, therefore a char has been used. However if greater than 3000 is entered by the user, the program should write back "number greater than 3000".
However, my new problem is, if i use a char it will only go upto 256, and if i use an int which has the range, it will not accept letters?
I have tried "unsigned long char", but this does not work.
How do i over come this problem?
Look forward to your advice.
Tuurbo46
-
Code:
Something like this, but its out of range:
char c = 0;
scanf("%c", &c);
if((c<'0')||(c>'9'))
{
printf("Invalid input\n");
}
else if(c>'3000')
{
printf("number greater than 3000");
-
I'm not sure what you are actually asking: I presume that what you are really looking for is either:
1. A way to read an integer, checking each character to see if the character is valid.
2. Check if what you read (using integer format to scanf()) was accepted by scanf().
The second option is the easier one:
The function scanf() will return "the number of correctly entered fields", so if you do
Code:
int n;
int r;
r = scanf("%d", &n);
if (r == 1) {
// Something got accepted as a number.
} else {
// Error, nothing accepted.
}
The above code will not accept "abc", but WILL accept "1234abc" as 1234, leaving "abc" in the input buffer. Another scanf() trying to read an integer from the input buffer of "abc" will not accept the further input of "abc".
Alternatively, you use getchar() to read each character, and you "build" the number up yourself. This is possibly what you are supposed to do.
Code:
int c;
int n;
do {
c = getchar();
if (isdigit(c)) {
// form a number
} else if (c == '\n') {
// done - but may be "empty" number.
} else {
// Error - something that wasn't a digit entered.
}
} while (moretodo);
This will ensure that ALL the input was accepted, and that there was no input beyond the "number".
Note that BOTH will require you to also remove any "garbage" from the input buffer if the input isn't accepted.
--
Mats
-
Hi,
Im trying to do a integer numbers to roman numeral conversion. I have the program working but i cannot get the error checking working with scanf. The requirements are as follows.
1) Covert integer numbers to roman numerals - done
2) If a letter or other none integer number is entered, display invalid input.
3) If number is greater than 3000, display number greater than 3000.
My problem is, if i use char, it does not have the range on 3000. If i use int, scanf will not read other letters, other than integers?
Im sure im making this more compliated than it actually is?
Should i use sscanf?
Cheers tuurbo46
-
So, the decision is what constitutes "non-integer number".
You will in one form or another, need to convert a string of characters into a number - but scanf() will in the "simple" case do that for you. However, that assumes we accept "1234abc" as a valid input, as there's no trivial check we can do to detect this particular error.
If we have to print an error for "1234abc", then the most immediate solution is to read a character at a time - this character will have the ASCII code of one digit for each input, so although the data would be 1-byte, and have a range of -128..127 (or unsigned char 0..255), but the data you will get is a single digit '0'..'9' each time. So you will need to do a conversion into an integer - consider this as the same task as if you where given a number at a time and had to come up with what the whole number is. It is not very hard to do, but involves a little loop.
Once you have an integer, you can easily check if it's above 3000 and print an error.
--
Mats
-
Hi,
Please can you break this down a bit for me, i just use scanf as a black box, and i dont really understand any further. As shown in the examples below, if i enter 1111, scanf returns 1111, but if i enter abcd, 0 is returned. I understand this means it is false, so therefore do i display "false input" if a zero is returned?
Code:
#include <cstdlib>
#include <stdio.h>
int main()
{
int b = 0;
int c = 0;
/* 1111 is entered */
printf("Please Enter integer number\n\n");
scanf("%d", &b);
printf("%d\n", b); /* 1111 is returned */
/* abcd is entered */
printf("Please Enter integer number\n\n");
scanf("%d", &c);
printf("%d\n", c); /* 0 is returned */
system("PAUSE");
return EXIT_SUCCESS;
}