473,473 Members | 2,282 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

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?

Oct 31 '07 #1
39 2072
In <11*********************@o80g2000hse.googlegroups. com"emre esirik(hacettepe computer science and engineering)" <em********@gmail.comwrites:
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?
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
go****@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Oct 31 '07 #2
emre esirik(hacettepe computer science and engineering) wrote:
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.
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.
Oct 31 '07 #3
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

Oct 31 '07 #4
John Gordon wrote:
In <11*********************@o80g2000hse.googlegroups. com"emre
esirik(hacettepe computer science and engineering)"
<em********@gmail.comwrites:
>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?

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

Oct 31 '07 #5
In <fg**********@aioe.orgsantosh <sa*********@gmail.comwrites:
John Gordon wrote:
string input[80];
What is this 'string' type?
Oops! My mistake, should be 'char' instead of course.
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
go****@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Oct 31 '07 #6
fgets() and strtol().

Oct 31 '07 #7
On Oct 31, 6:12 pm, vipvipvipvipvip...@gmail.com wrote:
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.

Oct 31 '07 #8
emre esirik(hacettepe computer science and engineering) wrote:
>
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
Nov 1 '07 #9
andreyvul wrote:
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
Nov 1 '07 #10
Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:

<snip>
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
Nov 1 '07 #11
On Nov 1, 2:23 am, Coos Haak <chfo...@hccnet.nlwrote:
Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:

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

Nov 1 '07 #12
On Thu, 1 Nov 2007 01:23:17 +0100, Coos Haak <ch*****@hccnet.nlwrote
in comp.lang.c:
Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:

<snip>
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
Nov 1 '07 #13
On Wed, 31 Oct 2007 16:33:33 -0700, andreyvul <an********@gmail.com>
wrote in comp.lang.c:
On Oct 31, 6:12 pm, vipvipvipvipvip...@gmail.com wrote:
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.
/* a char-
encoded digit or a NULL*/
/* (end-of-
string terminator) */
goto enter_again;
The line above is a valid goto statement.
n_mines = atoi(str);
At least you did manage to use the generally unsafe atoi() function
safely here, I'll give you that.
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.
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.
#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
Nov 1 '07 #14
vi****************@gmail.com writes:
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) ks***@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"
Nov 1 '07 #15
vi****************@gmail.com said:
On Nov 1, 2:23 am, Coos Haak <chfo...@hccnet.nlwrote:
>Op Thu, 01 Nov 2007 02:31:53 +0530 schreef santosh:

<snip>
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
Nov 1 '07 #16
pete wrote, On 01/11/07 00:11:
andreyvul wrote:
> 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
Nov 1 '07 #17
vi****************@gmail.com wrote:
pete:
Your `bulletproof' way can be replaced to 6 lines, fgets(), ret =
strtol(), if(error_check), this, else, that.
Post the program.

--
pete
Nov 1 '07 #18
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?

Nov 1 '07 #19
In <11**********************@v3g2000hsg.googlegroups. com"emre esirik(hacettepe computer science and engineering)" <em********@gmail.comwrites:
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
go****@panix.com B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

Nov 1 '07 #20
On Nov 1, 10:23 am, "emre esirik(hacettepe computer science and
engineering)" <emreesi...@gmail.comwrote:
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

Nov 1 '07 #21
"emre esirik(hacettepe computer science and engineering)" wrote:
>
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

Nov 1 '07 #22
CBFalconer wrote:
"emre esirik(hacettepe computer science and engineering)" wrote:
>>
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>

Nov 1 '07 #23
CBFalconer wrote, On 01/11/07 16:12:
"emre esirik(hacettepe computer science and engineering)" wrote:
>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>
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...
unsigned int rdvalue(FILE *f) {
unsigned int ch, value, err;

value = err = 0;
unsigned int ch;
unsigned int value = 0;
unsigned int 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 */
while ((ch=getc(f)) != EOF && isdigit(ch))
ch = ch - '0'; /* form digit value */
ch -= '0';
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.
/* 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.
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
Nov 1 '07 #24
Flash Gordon wrote:
>
pete wrote, On 01/11/07 00:11:
andreyvul wrote:
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
Nov 1 '07 #25
Flash Gordon wrote:
CBFalconer wrote, On 01/11/07 16:12:
.... snip ...
>
> 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.
>
> /* 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 ...
>
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

Nov 2 '07 #26
On Nov 1, 7:23 am, "emre esirik(hacettepe computer science and
engineering)" <emreesi...@gmail.comwrote:
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.

Nov 3 '07 #27
CBFalconer wrote, On 01/11/07 23:47:
Flash Gordon wrote:
>CBFalconer wrote, On 01/11/07 16:12:
... snip ...
>> 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.
>> /* 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 ...
>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
Nov 4 '07 #28
"pete" <pf*****@mindspring.coma écrit dans le message de news:
47***********@mindspring.com...
emre esirik(hacettepe computer science and engineering) wrote:
>>
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.
Nov 6 '07 #29
On Thu, 01 Nov 2007 11:12:04 -0500, CBFalconer <cb********@yahoo.com>
wrote:
"emre esirik(hacettepe computer science and engineering)" wrote:
<snip homework>
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:
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.
/* 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
Nov 12 '07 #30
Charlie Gordon wrote:
>
"pete" <pf*****@mindspring.coma écrit dans le message de news:
47***********@mindspring.com...
emre esirik(hacettepe computer science and engineering) wrote:
>
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
Nov 13 '07 #31
pete wrote:
>
vi****************@gmail.com wrote:
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
Nov 14 '07 #32
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.
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
Nov 14 '07 #33
David Thompson wrote:
CBFalconer <cb********@yahoo.comwrote:
.... snip ...
>
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:
>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

Nov 17 '07 #34
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.

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

Nov 17 '07 #35
CBFalconer wrote:
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.
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) <ks***@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"
Nov 17 '07 #36
CBFalconer wrote:
>
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.

--
pete
Nov 17 '07 #37
pete wrote:
CBFalconer wrote:
>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. 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) ks***@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"
Nov 18 '07 #38
Keith Thompson wrote:
>
pete wrote:
CBFalconer wrote:
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)

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.
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
Nov 18 '07 #39
Keith Thompson wrote:
CBFalconer wrote:
>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.

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

Nov 18 '07 #40

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Dan S | last post by:
My application asks the user to enter in a date - in the mm/dd/yyyy format. Is there any quick and easy way to verify the date the user enters is formatted correctly? Right now I'm calling...
8
by: kittykat | last post by:
Hi, could someone please check my code? its asking the user to enter 3 letters, and check to see if these letters exist in the text file. i know ive done something wrong. can someone fix my code...
2
by: CR | last post by:
having a problem with the final strcpy of filename from *argv into a structure containing an array with 20 elements called fname It seems that strcpy & strncpy aren't stopping after null is found...
19
by: wetherbean | last post by:
Hi group..I am writing a playlist management protocol where I have a file that holds all the playlists and a file that holds all the songs....before a playlist is created I need to check to see if...
51
by: moosdau | last post by:
my code: do { printf("please input the dividend and the divisor.\n"); if(!scanf("%d%d",&dend,&dor)) { temp1=1; fflush(stdin); } else
2
by: AdINo | last post by:
Below is my coding , how do i check whether the user input is interger or not ...... because if the user entered a integer i would like to ask the user to re-enter ...... meaning this program will...
17
by: wswilson | last post by:
In python, I could write: a = 1 if a in : do something... In c (and many other languages):
7
by: xiaolim | last post by:
hi, sorry to disturb again, currently i have an assignment on stacks and as show in the the title, i need to use stacks to determine palindrome. i've done part of my code, here it is: //...
15
by: puzzlecracker | last post by:
What is the quickest way to check that the following: const line; only contains whitespace, in which case to ignore it. something along these lines: isspacedLine(line); Thanks
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.