Puzzle!

T

Tak

Some days ago, I written a mini program like this:
#include <stdio.h>

int main()
{
char c;
int n;

scanf("%d",&n);
c = getchar();

return 0;
}

I want to assign n and c specific values,for example,give n and c
values of 5 and 'x' in fact when I input 5 then "enter",the program
is finish.I know when I press "Enter", I assigned '\n' to variable c,
But how can I avoid this?
 
W

Walter Roberson

Some days ago, I written a mini program like this:
#include <stdio.h>
int main()
{
char c;
int n;
scanf("%d",&n);
c = getchar();
return 0;
}
I want to assign n and c specific values,for example,give n and c
values of 5 and 'x' in fact when I input 5 then "enter",the program
is finish.I know when I press "Enter", I assigned '\n' to variable c,
But how can I avoid this?

while ( (c = getchar()) != EOF && c == '\n' ) { /* empty loop body */ }

Afterwards, c will either be EOF or a character other than \n .
This takes into account that the user might press return several times
before entering the desired character.

But to make this work, you will have to fix the problem the other poster
pointed out: that c should be of type int, not of type char.
 
K

Keith Thompson

Tak said:
Some days ago, I written a mini program like this:
#include <stdio.h>

int main()
{
char c;
int n;

scanf("%d",&n);
c = getchar();

return 0;
}

I want to assign n and c specific values,for example,give n and c
values of 5 and 'x' in fact when I input 5 then "enter",the program
is finish.I know when I press "Enter", I assigned '\n' to variable c,
But how can I avoid this?

(You've already mentioned in a followup that c needs to be an int.)

If you type "5x" and then <enter>, the program will assign 5 to n and
'x' to c.

In a real program, that would be a very unfriendly input format. If
you must use scanf, you should (a) check its return value, and (b) be
aware of the state the input stream will be in after the call, and act
accordingly; for example, you might want to read and ignore all
characters up to and including a newline (and don't forget to check
for EOF).

A better way to handle input is to read a line at a time using
fgets(), and then analyze the input line once you have it.
 
M

Mark McIntyre

Some days ago, I written a mini program like this:
#include <stdio.h>

scanf("%d",&n);
c = getchar();
I want to assign n and c specific values,for example,give n and c
values of 5 and 'x' in fact when I input 5 then "enter",the program
is finish.I know when I press "Enter", I assigned '\n' to variable c,
But how can I avoid this?

Don't use scanf.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
F

Flash Gordon

Tak wrote, On 02/06/07 04:31:
Then use what?

fgets (NOT gets, NEVER gets), getchar, getc, fgetc as appropriate. There
are gotchas on these so you need to read the documentation and search
the groups and the FAQ for further information.
 
A

Army1987

Mark McIntyre said:
Don't use scanf.

A little too extreme...
For example:

do {
int k = scanf("%d", &n);
switch (k) {
case EOF:
/* stdin is finished or there was something wrong. */
/* React accordingly. */
break;
case 0:
puts("Please enter an integer");
/* maybe write that to stderr? */
scanf("%*[^\n]%*c"); /*skip line*/
continue; /* yes, here break and continue would do the */
/* same thing... :) */
case 1:
break;
} while (k < 0);

Or to avoid strange problem if the number input is too large:

#include <limits.h>
#include <errno.h>
do {
long tmp;
int k = scanf("%ld", &tmp);
switch (k) {
case EOF:
/* stdin is finished or there was something wrong. */
/* React accordingly. */
break;
case 0:
puts("Please enter an integer");
/* maybe write that to stderr? */
scanf("%*[^\n]%*c"); /*skip line*/
continue; /* yes, here break and continue would do the */
/* same thing... :) */
case 1:
if (tmp < INT_MIN || tmp > INT_MAX) {
k = tmp < 0 ? INT_MIN : INT_MAX;
errno = ERANGE;
} else
k = tmp;
break;
} while (k < 0);
 
T

Tak

Tak wrote, On 02/06/07 04:31:


fgets (NOT gets, NEVER gets), getchar, getc, fgetc as appropriate. There
are gotchas on these so you need to read the documentation and search
the groups and the FAQ for further information.


I solve problems from ACM-ICPC, so fgets fgetc are not useful.
usually I solved like this :
int main()
{
int c;
int n;

scanf("%d",&n);
c = getchar();
c = getchar();

return 0;

}
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Tak said:
"Mark McIntyre" <[email protected]> ha scritto nel
messaggio
scanf("%*[^\n]%*c"); /*skip line*/

I've learnt that statement /scanf("%[^.]", str); /is usually dangerous
in some conditions.

You've learnt correctly, but that's not what's happening here. The problem
with scanf("%[^.]", str); is that you cannot know in advance whether enough
memory is available to store the string in str. scanf("%*[^\n]%*c");
discards everything it reads, instead of storing it.
 
A

Army1987

I solve problems from ACM-ICPC, so fgets fgetc are not useful.
usually I solved like this :
int main()
{
int c;
int n;

scanf("%d",&n);
c = getchar();
c = getchar();

return 0;

}

This is ok only as long as you know the only character between one number
and the character to be read will be the newline.
BTW, why do you assign c in both calls of getchar()? Isn't
getchar(); c = getchar(); ok?
 
T

Tak

This is ok only as long as you know the only character between one number
and the character to be read will be the newline.
BTW, why do you assign c in both calls of getchar()? Isn't
getchar(); c = getchar(); ok?

Yes , it seems cleaner.
 
R

Richard Heathfield

CBFalconer said:
Or ggets. I am pushing this with the idea of getting it
incorporated in the next version of the C standard.

For so long as it was your pet function, okay, fine - but if you're
going to try to get it into the C Standard, please at the very least
make it take a size_t to specify the maximum buffer allocation you're
prepared to tolerate. As it stands, it's wide open to a Denial of
Memory attack.

For the record, I'm not convinced that it would make a good addition to
the Standard. I'm not even convinced that my own fgetline function
(which is also freely available, and which I obviously prefer to ggets)
would make a good addition.
 
K

Keith Thompson

Army1987 said:
"Mark McIntyre" <[email protected]> ha scritto nel messaggio
Don't use scanf.

A little too extreme...
For example:

do {
int k = scanf("%d", &n); [snip]

Or to avoid strange problem if the number input is too large:

#include <limits.h>
#include <errno.h>
do {
long tmp;
int k = scanf("%ld", &tmp);
[snip]

C99 7.19.6.2p10:

If this object does not have an appropriate type, or if the result
of the conversion cannot be represented in the object, the
behavior is undefined.

This applies to fscanf, scanf, and sscanf. If I run your program and
enter a number that won't fit in type long, I risk nasal demons.

Using any of the *scanf functions with any of the numeric formats,
unless you have complete control over what appears in the input, is
dangerous. (IMHO, this is a flaw in the standard; this should have
been treated as a matching failure.)
 
M

Mark McIntyre

A little too extreme...

okay, fuller version

1) don't use scanf

2) (experts only) use scanf with the care you would take to handle
live scorpions while holding a sword point-first between your teeth.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
T

Tor Rustad

Keith said:
C99 7.19.6.2p10:

If this object does not have an appropriate type, or if the result
of the conversion cannot be represented in the object, the
behavior is undefined.

This applies to fscanf, scanf, and sscanf. If I run your program and
enter a number that won't fit in type long, I risk nasal demons.

Hmm... I can't say I agree with your interpretation Keith.

How can the %li conversion in scanf overflow a long object?
For %s and %c conversions, it's possible with such an overflow, but I
don't see the same for "numbers".

Of course, I assume there is no type mismatch... between conversion
specifiers and object.
 
T

Tor Rustad

Mark said:
okay, fuller version

1) don't use scanf

Very strange advice, the problem at hand, *might* have specified that OP
don't even need to check for input errors.

2) (experts only) use scanf with the care you would take to handle
live scorpions while holding a sword point-first between your teeth.

You can check for errors with scanf() too, it does have a return value
AND you do have the feof() and ferror() functions.
 

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

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top