how can we check to not enter the any string or char?

  • Thread starter emre esirik(hacettepe computer science and enginee
  • Start date
C

Chris Dollin

Philip said:
Jack Klein wrote:

It is unlikely but possible that the character set does not have the
digits 0-9 nicely in order.

It's not possible /in a conforming C implementation/.
Better to use isdigit().

But this may still be true.
 
S

santosh

Philip said:
Jack said:
On Oct 31, 6:12 pm, (e-mail address removed) 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 < 0x30 && str) || str > 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.


It is unlikely but possible that the character set does not have the
digits 0-9 nicely in order. Better to use isdigit().


I think C guarantees that the character sequence '0'... '9' have
sequentially increasing code values.
 
E

emre esirik(hacettepe computer science and enginee

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

John Gordon

In said:
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.
 
H

Hyuga

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_error(unsigned int
*number)

You can find it in stdio.h

Hyuga
 
C

CBFalconer

emre esirik(hacettepe computer science and engineering) said:
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.
 
S

santosh

CBFalconer said:
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>
 
F

Flash Gordon

CBFalconer wrote, On 01/11/07 16:12:
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.
 
J

John Bode

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

Please include the text you are responding to; not everyone uses
Google Groups to read Usenet, and messages don't always show up in the
order sent.

If this is in response to John Gordon's example, well, that's about as
easy as it gets in C (although I'd replace his test loop and call to
atoi() with a single call to strtol()).

Input validation is not trivial, especially in a language like C that
doesn't have the greatest text processing toolkit to begin with. To
repeat and expand on what others have said,

1. Read the input as a string, preferably using fgets();
2. Make sure the input doesn't contain non-numeric characters;
3. Convert the string to the equivalent integer value (both 2 and 3
can be taken care of by the library routine strtol())
4. Test the converted value against your range;
5. Give the user a chance to try again or to cancel if the input
fails the above tests.

Yes, it's more work than just calling scanf(). But if you want to
guard against non-numeric input, that's what you have to do.
 
P

pete

Flash said:
pete wrote, On 01/11/07 00:11:
andreyvul said:
if ((str < 0x30 && str) || str > 0x39)


I see two numbers that are nine apart from each other,
so I'm guessing that this is what you mean:

if ((str < '0' && str) || str > '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 != '\0' && !isdigit(str))
 
C

CBFalconer

Flash said:
CBFalconer wrote, On 01/11/07 16:12:
.... snip ...


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

Barry Schwarz

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

Flash Gordon

CBFalconer wrote, On 01/11/07 23:47:
No, this is intended to ensure the value fits into an unsigned int.

Which is not the OPs requirement.
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.
 
C

Charlie Gordon

pete said:
emre said:
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 :-(
 
C

Charlie Gordon

CBFalconer said:
No, this is intended to ensure the value fits into an unsigned int.

`Intent' is correct word: for a working implementation, the OP will have to
add more work.
The blatant mistake in this comparison is not the only one.
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.

But your code is obscure and incorrect, makes use of cumbersome constructs
such as comparing EOF to an unsigned int... There must be a more effective
way to educate the OP.
 
C

CBFalconer

Charlie said:
.... snip ...

But your code is obscure and incorrect, makes use of cumbersome
constructs such as comparing EOF to an unsigned int... There must
be a more effective way to educate the OP.

You didn't bother to quote any 'offensive' code, so I cannot
comment. I did mark it as untested. I don't agree that any of my
code is cumbersome.
 
C

Charlie Gordon

CBFalconer said:
You didn't bother to quote any 'offensive' code, so I cannot
comment. I did mark it as untested. I don't agree that any of my
code is cumbersome.

Yes I did:
No, this is intended to ensure the value fits into an unsigned int.

`Intent' is correct word: for a working implementation, the OP will have to
add more work.
The blatant mistake in this comparison is not the only one.

This test will be true the first time around, incorrectly diagnosing any
input as overflow.
Changing the comparison operator to < seems to fix the problem, but it gives
me a headache trying to prove correctness. It is also a shame to perform a
division at runtime for each character parsed.

Just proving that EOF can safely be compared to the unsigned int ch for the
intended semantics requires non trivial understanding of signed/unsigned
conversion and integer promotion rules.

Your code is cumbersome because it is not elegant.
 
C

CBFalconer

Charlie said:
Yes I did:

No you didn't. You only quoted a fraction of the routine. This
means I can't check, because the original post is long gone from
here. And I am not going to bother with google to check.
 
C

Charlie Gordon

CBFalconer said:
No you didn't. You only quoted a fraction of the routine. This
means I can't check, because the original post is long gone from
here. And I am not going to bother with google to check.

Come on, you are such a whiner.
Doesn't teranews let you retrieve your own posts from Usenet?
Don't you use a newreader with a threaded view to easily keep track of
ongoing discussions?
Thunderbird does that, even on Windows 98.
Your code sucks, so does your excuse, so does your signature, and so does
your attitude in general.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top