how can we check to not enter the any string or char? | | |
int n_mines;
printf("How many mines do you want in the minefield?");
scanf("%d", &n_mines);
while(n_mines>100 || n_mines<0)
{
printf("Please only enter between 1 and 100");
scanf("%d", &n_mines);
}
so I dont want to user can enter the string or char value,how can I
check it? | | | | re: how can we check to not enter the any string or char?
In <1193862410.106448.76840@o80g2000hse.googlegroups. com"emre esirik(hacettepe computer science and engineering)" <emreesirik@gmail.comwrites: Quote:
int n_mines;
printf("How many mines do you want in the minefield?");
scanf("%d", &n_mines);
Quote:
while(n_mines>100 || n_mines<0)
{
printf("Please only enter between 1 and 100");
scanf("%d", &n_mines);
}
Quote:
so I dont want to user can enter the string or char value,how can I
check it?
Read the input as a string first. Examine the string to see if it contains
any incorrect characters. If it does not, convert the string to its
decimal value.
string input[80];
int n_mines;
int i;
int good_input = 1;
printf("How many mines do you want in the minefield?");
fgets(input, sizeof(input), stdin);
for(i = 0; i < strlen(input); i++)
{
if(isalpha(input[i]))
{
// whoops! user entered a character
good_input = 0;
break;
}
}
if(good_input == 1)
{
n_mines = atoi(input);
}
else
{
printf("You must enter a number.\n");
}
--
John Gordon A is for Amy, who fell down the stairs gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies" | | | | re: how can we check to not enter the any string or char?
emre esirik(hacettepe computer science and engineering) wrote: Quote:
int n_mines;
printf("How many mines do you want in the minefield?");
scanf("%d", &n_mines);
scanf is a tricky function to use. If you do use it, you _must_ check
it's return value to ensure that it has succeeded.
If it fails it can, in certain situations, leave some input still in the
stdin's buffer, which will cause further calls to scanf to fail
repeatedly, until the stream is flushed. Quote:
while(n_mines>100 || n_mines<0)
{
printf("Please only enter between 1 and 100");
scanf("%d", &n_mines);
}
>
so I dont want to user can enter the string or char value,how can I
check it?
Frankly I advocate using fgets to input a line and strtoul or strtol to
convert to a numerical value. These functions provide more control and
better error reporting than either atoi or scanf/sscanf.
Also consider changing the above loop to a do/while one. | | | | re: how can we check to not enter the any string or char?
I am just started to learn C programming, thank you for reply but I
dont understand, it looks too difficult,
do you think is there any easy way for this,or its difficult to solve
for me as a beginner c programmer | | | | re: how can we check to not enter the any string or char?
John Gordon wrote: Quote:
In <1193862410.106448.76840@o80g2000hse.googlegroups. com"emre
esirik(hacettepe computer science and engineering)"
<emreesirik@gmail.comwrites:
> Quote:
>int n_mines;
>printf("How many mines do you want in the minefield?");
>scanf("%d", &n_mines);
> Quote:
>while(n_mines>100 || n_mines<0)
>{
>printf("Please only enter between 1 and 100");
>scanf("%d", &n_mines);
>}
> Quote:
> so I dont want to user can enter the string or char value,how can I
>check it?
>
Read the input as a string first. Examine the string to see if it
contains
any incorrect characters. If it does not, convert the string to its
decimal value.
>
string input[80];
What is this 'string' type? It's not defined in Standard C and if it is
C++'s std::string you might prefer to post in comp.lang.c++. Quote:
int n_mines;
int i;
int good_input = 1;
>
printf("How many mines do you want in the minefield?");
fgets(input, sizeof(input), stdin);
>
for(i = 0; i < strlen(input); i++)
{
if(isalpha(input[i]))
{
// whoops! user entered a character
good_input = 0;
break;
}
}
>
if(good_input == 1)
{
n_mines = atoi(input);
}
else
{
printf("You must enter a number.\n");
}
What about input like 23.3 or 34&%$3 and other combinations?
I suggest using isdigit instead of isalpha. Also cast the is* function's
arguments to unsigned char.
Also check fgets for success, otherwise input's contents will be
indeterminate. strtol might also be a better alternative to atoi
providing status reporting. | | | | re: how can we check to not enter the any string or char?
In <fgaqg3$fif$1@aioe.orgsantosh <santosh.k83@gmail.comwrites: Quote:
John Gordon wrote:
Quote:
What is this 'string' type?
Oops! My mistake, should be 'char' instead of course. Quote:
What about input like 23.3 or 34&%$3 and other combinations?
My intent was to demonstrate a concrete yet minimal solution upon which
the OP could improve, not to provide absolute final rock-solid code.
--
John Gordon A is for Amy, who fell down the stairs gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies" | | | | re: how can we check to not enter the any string or char?
fgets() and strtol(). | | | | re: how can we check to not enter the any string or char?
On Oct 31, 6:12 pm, vipvipvipvipvip...@gmail.com wrote: Quote:
fgets() and strtol().
fgets(str, 4, stdin) to be specific
also, there are only up to 4 input bytes, so the loop should be
rewritten to this:
char[4] str;
int i = 0, n_mines = 0;
while (1) {
fgets(str, 4, stdin);
for (i = 0; i < 4; i++)
if ((str[i] < 0x30 && str[i]) || str[i] 0x39) /* check ascii
value if it's not */
/* a char-
encoded digit or a NULL*/
/* (end-of-
string terminator) */
goto enter_again;
n_mines = atoi(str);
if (n_mines < 1 || n_mines 100)
goto enter_again:
enter_again:
printf("Please only enter between 1 and 100");
}
Note: in this situation, a goto was useful. However, gotos are like
#defines and should only be used sparingly.
Also, I hope you meant no tabs, spaces, or other control chars,
because the test checks for numbers only.
Also, you did not initialize n_mines before the loop. This may result
in undefined behavior if you are not careful to later initialize it,
especially in if- and switch-statements. C does not automatically zero
out variables before first use, so initialize your variables at the
top, when they are declared. | | | | re: how can we check to not enter the any string or char?
emre esirik(hacettepe computer science and engineering) wrote: Quote:
>
int n_mines;
printf("How many mines do you want in the minefield?");
scanf("%d", &n_mines);
>
while(n_mines>100 || n_mines<0)
{
printf("Please only enter between 1 and 100");
scanf("%d", &n_mines);
}
>
so I dont want to user can enter the string or char value,
how can I check it?
/* BEGIN n_mines.c */
/*
** Bulletproof numeric input with fscanf.
*/
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 4
#define str(x) # x
#define xstr(x) str(x)
int main(void)
{
int rc;
char array[LENGTH + 1];
long number;
int n_mines;
for (;;) {
printf("How many mines do you want in the minefield?: ");
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0 || rc == EOF) {
array[0] = '\0';
number = 0;
} else {
number = strtol(array, NULL, 10);
}
if (number 100 || number < 1) {
printf("Please only enter between 1 and 100\n");
} else {
n_mines = number;
printf("\nn_mines is %d.\n", n_mines);
break;
}
}
return 0;
}
/* END n_mines.c */
--
pete | | | | re: how can we check to not enter the any string or char?
andreyvul wrote: Quote:
if ((str[i] < 0x30 && str[i]) || str[i] 0x39)
I see two numbers that are nine apart from each other,
so I'm guessing that this is what you mean:
if ((str[i] < '0' && str[i]) || str[i] '9')
--
pete | | | | re: how can we check to not enter the any string or char?
Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:
<snip> Quote:
What about input like 23.3 or 34&%$3 and other combinations?
I suggest using isdigit instead of isalpha. Also cast the is* function's
arguments to unsigned char.
Why? I thought an int is expected. And char is promoted to int anyway,
signed or not.
--
Coos | | | | re: how can we check to not enter the any string or char?
On Nov 1, 2:23 am, Coos Haak <chfo...@hccnet.nlwrote: Quote:
Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:
>
<snip>
> Quote:
What about input like 23.3 or 34&%$3 and other combinations?
I suggest using isdigit instead of isalpha. Also cast the is* function's
arguments to unsigned char.
>
Why? I thought an int is expected. And char is promoted to int anyway,
signed or not.
You should cast to (unsigned char) only the argument of to*()
functions.
pete:
Your `bulletproof' way can be replaced to 6 lines, fgets(), ret =
strtol(), if(error_check), this, else, that. | | | | re: how can we check to not enter the any string or char?
On Thu, 1 Nov 2007 01:23:17 +0100, Coos Haak <chforth@hccnet.nlwrote
in comp.lang.c: Quote:
Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:
>
<snip>
> Quote:
What about input like 23.3 or 34&%$3 and other combinations?
I suggest using isdigit instead of isalpha. Also cast the is* function's
arguments to unsigned char.
Why? I thought an int is expected. And char is promoted to int anyway,
signed or not.
To avoid undefined behavior, that's why. The is* and to* functions
accept argument of type in ***in the range of 0 through UCHAR_MAX***,
or with the value EOF.
On implementations where plain char is signed, which is most of them
these days, a char can have a negative value, and will promote to an
int containing the same negative value. That just might happen to be
the value of EOF, which is required to be a negative int value, but
most likely will not be.
So on such an implementation, passing a signed character with a
negative value to an is* or to* function has at least a 125/126 chance
of producing undefined behavior.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html | | | | re: how can we check to not enter the any string or char?
On Wed, 31 Oct 2007 16:33:33 -0700, andreyvul <andrey.vul@gmail.com>
wrote in comp.lang.c: Quote:
On Oct 31, 6:12 pm, vipvipvipvipvip...@gmail.com wrote: Quote:
fgets() and strtol().
>
fgets(str, 4, stdin) to be specific
>
also, there are only up to 4 input bytes, so the loop should be
rewritten to this:
char[4] str;
int i = 0, n_mines = 0;
while (1) {
fgets(str, 4, stdin);
for (i = 0; i < 4; i++)
if ((str[i] < 0x30 && str[i]) || str[i] 0x39) /* check ascii
value if it's not */
But what if the platform does not use ASCII? C does not require it.
This is extremely foolish, when using '0' and '9' instead of 0x30 and
0x39 guarantees portability to any implementation of C now and
forever. Quote:
/* a char-
encoded digit or a NULL*/
/* (end-of-
string terminator) */
goto enter_again;
The line above is a valid goto statement. Quote:
n_mines = atoi(str);
At least you did manage to use the generally unsafe atoi() function
safely here, I'll give you that. Quote:
if (n_mines < 1 || n_mines 100)
goto enter_again:
The line above is a syntax error, not a valid goto statement. And
it's completely unnecessary, since the label immediately follows the
botched goto. Quote:
enter_again:
printf("Please only enter between 1 and 100");
}
>
Note: in this situation, a goto was useful. However, gotos are like
There are very few situations where a goto is useful and justified.
This mess is not one of them. Why "mess"? There is no way out of the
loop, no matter what is entered. Quote:
#defines and should only be used sparingly.
Also, I hope you meant no tabs, spaces, or other control chars,
because the test checks for numbers only.
Also, you did not initialize n_mines before the loop. This may result
in undefined behavior if you are not careful to later initialize it,
especially in if- and switch-statements. C does not automatically zero
out variables before first use, so initialize your variables at the
top, when they are declared.
That last sentence of yours is only partially correct. C does not
automatically zero out automatic variables before use. It most
certainly initializes all objects with static storage duration to 0 if
they do not have an explicit initializer.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html | | | | re: how can we check to not enter the any string or char? vipvipvipvipvip.ru@gmail.com writes: Quote:
fgets() and strtol().
When you post a followup, please retain enough context from the parent
article so your followup makes sense on its own.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister" | | | | re: how can we check to not enter the any string or char? vipvipvipvipvip.ru@gmail.com said: Quote:
On Nov 1, 2:23 am, Coos Haak <chfo...@hccnet.nlwrote: Quote:
>Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:
>>
><snip>
>> Quote:
What about input like 23.3 or 34&%$3 and other combinations?
I suggest using isdigit instead of isalpha. Also cast the is*
function's arguments to unsigned char.
>>
>Why? I thought an int is expected. And char is promoted to int anyway,
>signed or not.
>
You should cast to (unsigned char) only the argument of to*()
functions.
Wrong. See Jack's explanation.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999 | | | | re: how can we check to not enter the any string or char?
pete wrote, On 01/11/07 00:11: Quote:
andreyvul wrote:
> Quote:
> if ((str[i] < 0x30 && str[i]) || str[i] 0x39)
>
I see two numbers that are nine apart from each other,
so I'm guessing that this is what you mean:
>
if ((str[i] < '0' && str[i]) || str[i] '9')
Still horrible, I would almost always use isdigit() rather than
comparing against '0' and '9'. I don't expect it to be more efficient
(although it could be) just more readable.
--
Flash Gordon | | | | re: how can we check to not enter the any string or char? vipvipvipvipvip.ru@gmail.com wrote: Quote:
pete:
Your `bulletproof' way can be replaced to 6 lines, fgets(), ret =
strtol(), if(error_check), this, else, that.
Post the program.
--
pete | | | | re: how can we check to not enter the any string or char?
friends thank you for all but I am new programmer, I am just learning
C language at hacettepe university comp.science and eng.
so I still dont understand anything,
just I want to check if user enter numbers, it only can be between
1-100 and if user enter character, give a error,"you cant use
character,enter again,
so how can I do this by the easiest way? | | | | re: how can we check to not enter the any string or char?
In <1193927016.834197.191640@v3g2000hsg.googlegroups. com"emre esirik(hacettepe computer science and engineering)" <emreesirik@gmail.comwrites: Quote:
friends thank you for all but I am new programmer, I am just learning
C language at hacettepe university comp.science and eng.
so I still dont understand anything,
just I want to check if user enter numbers, it only can be between
1-100 and if user enter character, give a error,"you cant use
character,enter again,
so how can I do this by the easiest way?
Read the input as a string.
Examine each character in the string.
If any character is an alphabetic letter, give an error.
Otherwise, covert the string to a number.
--
John Gordon A is for Amy, who fell down the stairs gordon@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies" | | | | re: how can we check to not enter the any string or char?
On Nov 1, 10:23 am, "emre esirik(hacettepe computer science and
engineering)" <emreesi...@gmail.comwrote: Quote:
friends thank you for all but I am new programmer, I am just learning
C language at hacettepe university comp.science and eng.
so I still dont understand anything,
just I want to check if user enter numbers, it only can be between
1-100 and if user enter character, give a error,"you cant use
character,enter again,
so how can I do this by the easiest way?
You've been shown several examples that you could pick and choose
pieces from. There is no "easiest way", except of course for void
enter_number_and_if_user_enter_character_give_a_er ror(unsigned int
*number)
You can find it in stdio.h
Hyuga | | | | re: how can we check to not enter the any string or char?
"emre esirik(hacettepe computer science and engineering)" wrote: Quote:
>
friends thank you for all but I am new programmer, I am just
learning C language at hacettepe university comp.science and eng.
so I still dont understand anything, just I want to check if user
enter numbers, it only can be between 1-100 and if user enter
character, give a error,"you cant use character,enter again,
so how can I do this by the easiest way?
First, learn to quote what you are replying to. Then learn to snip
the portions that have no bearing, and to retain the attributions.
This makes your article stand by itself, which is necessary since
there are no transmission guarantees with the Usenet system.
(Google is just a poor interface to Usenet).
The cleanest way is to input chars until you have something that
will not fit. For example:
unsigned int rdvalue(FILE *f) {
unsigned int ch, value, err;
value = err = 0;
while (EOF != (ch = getc(f))) {
/* ch contains an int, which is the value of the char */
if (!isdigit(ch)) break; /* Only interested in digits */
ch = ch - '0'; /* form digit value */
if (((UINT_MAX - ch) / 10) value) {
/* overflow detected, decide what to do */
ch = ch + '0'; /* restore char value */
break;
}
value = 10 * value + ch;
}
ungetc(ch, f); /* keep exit char for the user */
return err;
} /* untested - you check it out */
Look up the standard include files needed to handle anything not
defined above. The result is acquired without needing any buffers,
accepts any number of leading zeroes, etc. Once this is working
you can use it to input signed ints, etc. Or you can first expand
it to handle longs.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com | | | | re: how can we check to not enter the any string or char?
CBFalconer wrote: Quote:
"emre esirik(hacettepe computer science and engineering)" wrote: Quote:
>>
>friends thank you for all but I am new programmer, I am just
>learning C language at hacettepe university comp.science and eng.
>so I still dont understand anything, just I want to check if user
>enter numbers, it only can be between 1-100 and if user enter
>character, give a error,"you cant use character,enter again,
>so how can I do this by the easiest way?
>
First, learn to quote what you are replying to. Then learn to snip
the portions that have no bearing, and to retain the attributions.
This makes your article stand by itself, which is necessary since
there are no transmission guarantees with the Usenet system.
(Google is just a poor interface to Usenet).
Some posters have claimed that the above is an exaggeration. I can
however, speaking from personal experience, say that CBFalconer is
*not* exaggerating.
I use two accounts to access Usenet, one with aioe.org and another with
motzarella.org. Over the past few weeks I have noted that, for some
strange reason, the motzarella server does not seem to carry any of
Keith Thompson's posts. Fortunately however, since most members include
enough context in their posts, I was still able to glean the bulk of
Keith's contributions from the posts of his respondents. To read his
articles themselves I had to switch over to the aioe server.
This illustrates that in Usenet, up-thread articles are not guaranteed
to be available on all servers and at all times. That is one reason why
quoting context with proper attributions is vital to getting the most
out of a discussion.
<snip> | | | | re: how can we check to not enter the any string or char?
CBFalconer wrote, On 01/11/07 16:12: Quote:
"emre esirik(hacettepe computer science and engineering)" wrote: Quote:
>friends thank you for all but I am new programmer, I am just
>learning C language at hacettepe university comp.science and eng.
>so I still dont understand anything, just I want to check if user
>enter numbers, it only can be between 1-100 and if user enter
>character, give a error,"you cant use character,enter again,
>so how can I do this by the easiest way?
<snip> Quote:
The cleanest way is to input chars until you have something that
will not fit. For example:
Reading a line and then using strtol is cleaner in my opinion, it has
limitations but requires a lot less code. Also, there are several
changes I would make to your version... Quote:
unsigned int rdvalue(FILE *f) {
unsigned int ch, value, err;
>
value = err = 0;
unsigned int ch;
unsigned int value = 0;
unsigned int err = 0; Quote:
while (EOF != (ch = getc(f))) {
/* ch contains an int, which is the value of the char */
if (!isdigit(ch)) break; /* Only interested in digits */
while ((ch=getc(f)) != EOF && isdigit(ch)) Quote:
ch = ch - '0'; /* form digit value */
ch -= '0'; Quote:
if (((UINT_MAX - ch) / 10) value) {
This is meant to be a bounded input, pass in and test against the bounds
allowed rather than some other value. Quote:
/* overflow detected, decide what to do */
ch = ch + '0'; /* restore char value */
break;
}
value = 10 * value + ch;
}
ungetc(ch, f); /* keep exit char for the user */
return err;
} /* untested - you check it out */
Still untested by me. Quote:
Look up the standard include files needed to handle anything not
defined above. The result is acquired without needing any buffers,
accepts any number of leading zeroes, etc. Once this is working
you can use it to input signed ints, etc. Or you can first expand
it to handle longs.
Of course, you have just done most of this chaps homework.
--
Flash Gordon | | | | re: how can we check to not enter the any string or char?
Flash Gordon wrote: Quote:
>
pete wrote, On 01/11/07 00:11: Quote:
andreyvul wrote: Quote:
if ((str[i] < 0x30 && str[i]) || str[i] 0x39)
I see two numbers that are nine apart from each other,
so I'm guessing that this is what you mean:
if ((str[i] < '0' && str[i]) || str[i] '9')
>
Still horrible, I would almost always use isdigit() rather than
comparing against '0' and '9'. I don't expect it to be more efficient
(although it could be) just more readable.
if (str[i] != '\0' && !isdigit(str[i]))
--
pete | | | | re: how can we check to not enter the any string or char?
Flash Gordon wrote: Quote:
CBFalconer wrote, On 01/11/07 16:12:
>
.... snip ... Quote:
> Quote:
> if (((UINT_MAX - ch) / 10) value) {
>
This is meant to be a bounded input, pass in and test against the bounds
allowed rather than some other value.
No, this is intended to ensure the value fits into an unsigned int. Quote:
> Quote:
> /* overflow detected, decide what to do */
> ch = ch + '0'; /* restore char value */
> break;
> }
> value = 10 * value + ch;
> }
> ungetc(ch, f); /* keep exit char for the user */
> return err;
>} /* untested - you check it out */
>
Still untested by me.
>
.... snip ... Quote:
>
Of course, you have just done most of this chaps homework.
No I haven't. The function is incomplete. Nobody seems to notice
that it doesn't bother to return value, as it should, and that err
should be a further parameter (*err). What I have done is
encourage him to develop a standard reusable input mechanism, whose
value can be checked by the caller, and which doesn't require
(possibly) long strings etc.
--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com | | | | re: how can we check to not enter the any string or char?
On Nov 1, 7:23 am, "emre esirik(hacettepe computer science and
engineering)" <emreesi...@gmail.comwrote: Quote:
friends thank you for all but I am new programmer, I am just learning
C language at hacettepe university comp.science and eng.
so I still dont understand anything,
just I want to check if user enter numbers, it only can be between
1-100 and if user enter character, give a error,"you cant use
character,enter again,
so how can I do this by the easiest way?
The simplest way is to use an input function that will accept whatever
the user enters and store it in a string. fgets is very good at
this. Once you have the data, you can then use strtol to 1) convert
the string to an integer value, and 2) determine where the conversion
process stopped. If you then check the first character that wasn't
converted, you will know whether the user's input was valid.
If the character in question is '\n', then you know you received all
the input and converted it completely (then and only then you can
check to see if the number is in range). If it is a '\0', then the
user entered more input that would fit in your string. If it is any
other value, then the user entered that non-digit character (plus
perhaps others but one is enough to render the input invalid).
We will not write the code for you. You need to research these
functions in your reference and write a function that uses them as
described. If you have problems with the code not working, post it
with a detailed description of the problem and you will get detailed
help. | | | | re: how can we check to not enter the any string or char?
CBFalconer wrote, On 01/11/07 23:47: Quote:
Flash Gordon wrote: Quote:
>CBFalconer wrote, On 01/11/07 16:12:
>>
... snip ... Quote: Quote:
>> if (((UINT_MAX - ch) / 10) value) {
>This is meant to be a bounded input, pass in and test against the bounds
>allowed rather than some other value.
>
No, this is intended to ensure the value fits into an unsigned int.
Which is not the OPs requirement. Quote: Quote: Quote:
>> /* overflow detected, decide what to do */
>> ch = ch + '0'; /* restore char value */
>> break;
>> }
>> value = 10 * value + ch;
>> }
>> ungetc(ch, f); /* keep exit char for the user */
>> return err;
>>} /* untested - you check it out */
>Still untested by me.
>>
... snip ... Quote:
>Of course, you have just done most of this chaps homework.
>
No I haven't. The function is incomplete. Nobody seems to notice
that it doesn't bother to return value, as it should, and that err
should be a further parameter (*err). What I have done is
encourage him to develop a standard reusable input mechanism, whose
value can be checked by the caller, and which doesn't require
(possibly) long strings etc.
I.e. you have done most of his homework by providing something close to
a complete solution. I did NOT say you had done it all nor that I had
fully reviewed your code.
--
Flash Gordon | | | | re: how can we check to not enter the any string or char?
"pete" <pfiland@mindspring.coma écrit dans le message de news: 472917DC.425A@mindspring.com... Quote:
emre esirik(hacettepe computer science and engineering) wrote: Quote:
>>
>int n_mines;
>printf("How many mines do you want in the minefield?");
> scanf("%d", &n_mines);
>>
> while(n_mines>100 || n_mines<0)
> {
> printf("Please only enter between 1 and 100");
> scanf("%d", &n_mines);
> }
>>
> so I dont want to user can enter the string or char value,
> how can I check it?
>
/* BEGIN n_mines.c */
/*
** Bulletproof numeric input with fscanf.
*/
#include <stdio.h>
#include <stdlib.h>
>
#define LENGTH 4
#define str(x) # x
#define xstr(x) str(x)
>
int main(void)
{
int rc;
char array[LENGTH + 1];
long number;
int n_mines;
>
for (;;) {
printf("How many mines do you want in the minefield?: ");
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0 || rc == EOF) {
array[0] = '\0';
number = 0;
} else {
number = strtol(array, NULL, 10);
}
if (number 100 || number < 1) {
printf("Please only enter between 1 and 100\n");
} else {
n_mines = number;
printf("\nn_mines is %d.\n", n_mines);
break;
}
}
return 0;
}
>
/* END n_mines.c */
This program does not let me type 000001 as a response to the question :-(
--
Chqrlie. | | | | re: how can we check to not enter the any string or char?
On Thu, 01 Nov 2007 11:12:04 -0500, CBFalconer <cbfalconer@yahoo.com>
wrote: Quote:
"emre esirik(hacettepe computer science and engineering)" wrote:
<snip homework> Quote:
The cleanest way is to input chars until you have something that
will not fit. For example:
>
Aside: I don't agree that's cleanest. I'm used to thinking of lexemes
as atomic, and for e.g. 123456789 to be understood on a 16-bit-int
system as 'error then (valid?) 6789' seems ugly _to me_. That said: Quote:
unsigned int rdvalue(FILE *f) {
unsigned int ch, value, err;
>
value = err = 0;
while (EOF != (ch = getc(f))) {
/* ch contains an int, which is the value of the char */
if (!isdigit(ch)) break; /* Only interested in digits */
ch = ch - '0'; /* form digit value */
if (((UINT_MAX - ch) / 10) value) {
.... this is backwards. Possibly as a result of the 'always put the
nonvariable on the left of comparison even if it isn't == which is the
only case that encourages mistakes' style, which I don't love.
Moreover, since unsigned (int and higher) arithmetic is well-defined
to wrap, it's perfectly safe, IMO clearer, and probably more efficient
to just do the multiply-add and then check for overflow=wrap. Quote:
/* overflow detected, decide what to do */
ch = ch + '0'; /* restore char value */
break;
}
value = 10 * value + ch;
}
ungetc(ch, f); /* keep exit char for the user */
return err;
} /* untested - you check it out */
I did. <GAs already noted, you don't return the value; and to use
inband error reporting -- which is a whole debate in itself -- you
need at least reasonably distinguishable error value(s). For unsigned
types it _may_ be reasonable to steal Uxxx_MAX or as it is also known
(unsigned xxx)-1 . For signed types this is usually harder.
- formerly david.thompson1 || achar(64) || worldnet.att.net | | | | re: how can we check to not enter the any string or char?
Charlie Gordon wrote: Quote:
>
"pete" <pfiland@mindspring.coma écrit dans le message de news: 472917DC.425A@mindspring.com... Quote:
emre esirik(hacettepe computer science and engineering) wrote: Quote:
>
int n_mines;
printf("How many mines do you want in the minefield?");
scanf("%d", &n_mines);
>
while(n_mines>100 || n_mines<0)
{
printf("Please only enter between 1 and 100");
scanf("%d", &n_mines);
}
>
so I dont want to user can enter the string or char value,
how can I check it?
/* BEGIN n_mines.c */
/*
** Bulletproof numeric input with fscanf.
*/
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 4
#define str(x) # x
#define xstr(x) str(x)
int main(void)
{
int rc;
char array[LENGTH + 1];
long number;
int n_mines;
for (;;) {
printf("How many mines do you want in the minefield?: ");
fflush(stdout);
rc = fscanf(stdin, "%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getc(stdin);
}
if (rc == 0 || rc == EOF) {
array[0] = '\0';
number = 0;
} else {
number = strtol(array, NULL, 10);
}
if (number 100 || number < 1) {
printf("Please only enter between 1 and 100\n");
} else {
n_mines = number;
printf("\nn_mines is %d.\n", n_mines);
break;
}
}
return 0;
}
/* END n_mines.c */
>
This program does not let me type 000001
as a response to the question :-(
That's the way that I want it to work.
If you want to specify how many more characters
beyond what are required for valid input,
the program should be able to read,
then I can change it.
--
pete | | | | re: how can we check to not enter the any string or char?
pete wrote: Quote:
> vipvipvipvipvip.ru@gmail.com wrote:
> Quote:
pete:
Your `bulletproof' way can be replaced to 6 lines, fgets(), ret =
strtol(), if(error_check), this, else, that.
>
Post the program.
Excuse me,
I also meant to explicitly call you a liar.
Liar.
--
pete | | | | re: how can we check to not enter the any string or char?
CBFalconer wrote: Quote:
The cleanest way is to input chars until you have something that
will not fit. For example:
>
unsigned int rdvalue(FILE *f) {
unsigned int ch, value, err;
>
value = err = 0;
while (EOF != (ch = getc(f))) {
/* ch contains an int, which is the value of the char */
Whether or not ((unsigned)EOF) equals ('0') or any other
printing character, is implementation defined.
The loop control expression is no good. Quote:
if (!isdigit(ch)) break; /* Only interested in digits */
ch = ch - '0'; /* form digit value */
if (((UINT_MAX - ch) / 10) value) {
/* overflow detected, decide what to do */
ch = ch + '0'; /* restore char value */
break;
}
value = 10 * value + ch;
}
ungetc(ch, f); /* keep exit char for the user */
return err;
} /* untested - you check it out */
I can read it well enough to see that it's wrong.
Using an int type to receive the return value of getc
is elementary stuff.
You're thinking too hard.
--
pete | | | | re: how can we check to not enter the any string or char?
David Thompson wrote: Quote:
CBFalconer <cbfalconer@yahoo.comwrote:
>
.... snip ... Quote:
>
Aside: I don't agree that's cleanest. I'm used to thinking of
lexemes as atomic, and for e.g. 123456789 to be understood on a
16-bit-int system as 'error then (valid?) 6789' seems ugly _to
me_. That said:
> Quote:
>unsigned int rdvalue(FILE *f) {
> unsigned int ch, value, err;
>>
> value = err = 0;
> while (EOF != (ch = getc(f))) {
> /* ch contains an int, which is the value of the char */
> if (!isdigit(ch)) break; /* Only interested in digits */
> ch = ch - '0'; /* form digit value */
> if (((UINT_MAX - ch) / 10) value) {
>
... this is backwards. Possibly as a result of the 'always put
the nonvariable on the left of comparison even if it isn't ==
which is the only case that encourages mistakes' style, which
I don't love.
>
Moreover, since unsigned (int and higher) arithmetic is well-
defined to wrap, it's perfectly safe, IMO clearer, and probably
more efficient to just do the multiply-add and then check for
overflow=wrap.
I disagree. The objective is to allow the user to recapture the
real value, if possible. To do this we must not discard any input
characters, but we must cease the inputting.
Yes, I think you are right, the overflow test is backwards. :_)
--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com | | | | re: how can we check to not enter the any string or char?
pete wrote: Quote:
CBFalconer wrote:
> Quote:
>The cleanest way is to input chars until you have something that
>will not fit. For example:
>>
>unsigned int rdvalue(FILE *f) {
> unsigned int ch, value, err;
>>
> value = err = 0;
> while (EOF != (ch = getc(f))) {
> /* ch contains an int, which is the value of the char */
>
Whether or not ((unsigned)EOF) equals ('0') or any other
printing character, is implementation defined.
>
The loop control expression is no good.
Try it. Then consider the conversion rules.
--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com | | | | re: how can we check to not enter the any string or char?
CBFalconer wrote: Quote:
pete wrote: Quote:
>CBFalconer wrote:
>> Quote:
>>The cleanest way is to input chars until you have something that
>>will not fit. For example:
>>>
>>unsigned int rdvalue(FILE *f) {
>> unsigned int ch, value, err;
>>>
>> value = err = 0;
>> while (EOF != (ch = getc(f))) {
>> /* ch contains an int, which is the value of the char */
>Whether or not ((unsigned)EOF) equals ('0') or any other
>printing character, is implementation defined.
>>
>The loop control expression is no good.
>
Try it. Then consider the conversion rules.
Ok. Suppose a call to getc() returns EOF, which has a negative value.
This value is converted to type unsigned int, which is well defined.
You then compare it to the value EOF, which succeeds.
If sizeof(int)==1, then there are potential problems with EOF matching a
valid character, but you have the same problem with signed int.
So the code happens to work, but it's too much work to confirm that.
getc() returns a result of type int. You should assign it to a variable
of type int. Keep it simple.
--
Keith Thompson (The_Other_Keith) <kst-u@mib.org>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister" | | | | re: how can we check to not enter the any string or char?
CBFalconer wrote: Quote:
>
pete wrote: Quote:
CBFalconer wrote: Quote:
The cleanest way is to input chars until you have something that
will not fit. For example:
>
unsigned int rdvalue(FILE *f) {
unsigned int ch, value, err;
>
value = err = 0;
while (EOF != (ch = getc(f))) {
/* ch contains an int, which is the value of the char */
Whether or not ((unsigned)EOF) equals ('0') or any other
printing character, is implementation defined.
The loop control expression is no good.
>
Try it. Then consider the conversion rules.
Consider the conversion rules first.
((unsigned)EOF) can be any value.
((unsigned)EOF) is what (ch) gets compared to.
--
pete | | | | re: how can we check to not enter the any string or char?
pete wrote: Quote:
CBFalconer wrote: Quote:
>pete wrote: Quote:
>>CBFalconer wrote:
>>>
>>>The cleanest way is to input chars until you have something that
>>>will not fit. For example:
>>>>
>>>unsigned int rdvalue(FILE *f) {
>>> unsigned int ch, value, err;
>>>>
>>> value = err = 0;
>>> while (EOF != (ch = getc(f))) {
>>> /* ch contains an int, which is the value of the char */
>>Whether or not ((unsigned)EOF) equals ('0') or any other
>>printing character, is implementation defined.
>>>
>>The loop control expression is no good.
>Try it. Then consider the conversion rules.
>
Consider the conversion rules first.
((unsigned)EOF) can be any value.
((unsigned)EOF) is what (ch) gets compared to.
EOF expands to an expression of type int with a negative value. Converting to
unsigned must yield a value larger than INT_MAX. ch, which may have the value
EOF, is converted to unsigned before the comparison, so if ch is EOF, the
comparison is in effect (unsigned)EOF != (unsigned)EOF.
But if ch had been declared as an int, we wouldn't have to have this discussion.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister" | | | | re: how can we check to not enter the any string or char?
Keith Thompson wrote: Quote:
>
pete wrote: Quote:
CBFalconer wrote: Quote:
pete wrote:
>CBFalconer wrote:
>>
>>The cleanest way is to input chars until you have something that
>>will not fit. For example:
>>>
>>unsigned int rdvalue(FILE *f) {
>> unsigned int ch, value, err;
>>>
>> value = err = 0;
>> while (EOF != (ch = getc(f))) {
>> /* ch contains an int, which is the value of the char */
>Whether or not ((unsigned)EOF) equals ('0') or any other
>printing character, is implementation defined.
>>
>The loop control expression is no good.
Try it. Then consider the conversion rules.
Consider the conversion rules first.
((unsigned)EOF) can be any value.
((unsigned)EOF) is what (ch) gets compared to.
>
EOF expands to an expression of type int with a negative value.
Converting to unsigned must yield a value larger than INT_MAX.
No.
If
( INT_MAX == UINT_MAX)
(-INT_MAX != INT_MIN)
( EOF == INT_MIN)
then
((unsigned)EOF == 0) Quote:
ch, which may have the value EOF,
is converted to unsigned before the comparison,
What?
ch is unsigned to begin with.
That's how (unsigned) gets into to this discussion. Quote:
so if ch is EOF,
the comparison is in effect (unsigned)EOF != (unsigned)EOF.
>
But if ch had been declared as an int,
we wouldn't have to have this discussion.
--
pete | | | | re: how can we check to not enter the any string or char?
Keith Thompson wrote: Quote:
CBFalconer wrote: Quote:
>pete wrote: Quote:
>>CBFalconer wrote:
>>>
>>>The cleanest way is to input chars until you have something
>>>that will not fit. For example:
>>>>
>>>unsigned int rdvalue(FILE *f) {
>>> unsigned int ch, value, err;
>>>>
>>> value = err = 0;
>>> while (EOF != (ch = getc(f))) {
>>> /* ch contains an int, which is the value of the char */
>>>
>>Whether or not ((unsigned)EOF) equals ('0') or any other
>>printing character, is implementation defined.
>>>
>>The loop control expression is no good.
>>
>Try it. Then consider the conversion rules.
>
Ok. Suppose a call to getc() returns EOF, which has a negative
value. This value is converted to type unsigned int, which is well
defined. You then compare it to the value EOF, which succeeds.
>
If sizeof(int)==1, then there are potential problems with EOF
matching a valid character, but you have the same problem with
signed int.
>
So the code happens to work, but it's too much work to confirm
that. getc() returns a result of type int. You should assign it
to a variable of type int. Keep it simple.
I did keep it simple. You snipped the rest of the routine, which
used unsigned arithmetic to detect overflows. Use of an int for ch
would create very awkward situations.
--
Chuck F (cbfalconer at maineline dot net)
<http://cbfalconer.home.att.net>
Try the download section.
--
Posted via a free Usenet account from http://www.teranews.com |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,467 network members.
|