By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,412 Members | 917 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,412 IT Pros & Developers. It's quick & easy.

Puzzle!

P: n/a
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?

Jun 1 '07 #1
Share this Question
Share on Google+
98 Replies


P: n/a
Tak
On 6 2 , 1 15 , Tak <kakat...@gmail.comwrote:
Some days ago, I written a mini program like this:
#include <stdio.h>

int main()
{
char c;
a mistake: "int c" not "char c"
int n;

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

return 0;

}

Jun 1 '07 #2

P: n/a
In article <11*********************@i13g2000prf.googlegroups. com>,
Tak <ka******@gmail.comwrote:
>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.

--
Prototypes are supertypes of their clones. -- maplesoft
Jun 1 '07 #3

P: n/a
Tak <ka******@gmail.comwrites:
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.

--
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"
Jun 1 '07 #4

P: n/a
Walter Roberson wrote:
>
.... snip ...
>
while ( (c = getchar()) != EOF && c == '\n' ) { /* empty loop body */ }
^^
{should be !=) :-)
>
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.
--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 1 '07 #5

P: n/a
On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
<ka******@gmail.comwrote:
>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
Jun 1 '07 #6

P: n/a
Tak
On 6 2 , 7 26 , Mark McIntyre <markmcint...@spamcop.netwrote:
On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak

<kakat...@gmail.comwrote:
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.
Then use what?
Jun 2 '07 #7

P: n/a

"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com...
On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
<ka******@gmail.comwrote:
>>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.
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);
Jun 2 '07 #8

P: n/a
Tak wrote, On 02/06/07 04:31:
On 6 2 , 7 26 , Mark McIntyre <markmcint...@spamcop.netwrote:
>On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak

<kakat...@gmail.comwrote:
>>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.

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.
--
Flash Gordon
Jun 2 '07 #9

P: n/a
Tak
On 6 2 , 3 58 , "Army1987" <please....@for.itwrote:
"Mark McIntyre" <markmcint...@spamcop.netha scritto nel messaggionews:hm********************************@4 ax.com...
<snip>
scanf("%*[^\n]%*c"); /*skip line*/
I've learnt that statement /scanf("%[^.]", str); /is usually dangerous
in some conditions.

Jun 2 '07 #10

P: n/a
Tak
On 6 2 , 3 39 , Flash Gordon <s...@flash-gordon.me.ukwrote:
Tak wrote, On 02/06/07 04:31:
On 6 2 , 7 26 , Mark McIntyre <markmcint...@spamcop.netwrote:
On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
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.

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;

}

Jun 2 '07 #11

P: n/a
Tak wrote:
On 6 2 , 3 58 , "Army1987" <please....@for.itwrote:
>"Mark McIntyre" <markmcint...@spamcop.netha scritto nel
messaggionews:hm********************************@ 4ax.com...
<snip>
> 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.
Jun 2 '07 #12

P: n/a

"Tak" <ka******@gmail.comha scritto nel messaggio
news:11*********************@a26g2000pre.googlegro ups.com...
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?
Jun 2 '07 #13

P: n/a
Tak
On 6 2 , 7 21 , "Army1987" <please....@for.itwrote:
"Tak" <kakat...@gmail.comha scritto nel messaggionews:11*********************@a26g2000pre. googlegroups.com...
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?
Yes , it seems cleaner.

Jun 2 '07 #14

P: n/a
Tak wrote:
>
.... snip ...
>
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;
}
I have no idea what ACM-ICPC is. However fgets, fgetc, getc, etc.
are all available in any standard C compliant system. That is one
of the purposes of having a standard.

scanf is generally not too useful in interactive work, and should
never be used without checking its return value.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 2 '07 #15

P: n/a
Flash Gordon wrote:
Tak wrote, On 02/06/07 04:31:
.... snip ...
>
>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.
Or ggets. I am pushing this with the idea of getting it
incorporated in the next version of the C standard. It's free.
See:

<http://cbfalconer.home.att.net/download/ggets.zip>

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 2 '07 #16

P: n/a
CBFalconer said:
Flash Gordon wrote:
>Tak wrote, On 02/06/07 04:31:
... snip ...
>>
>>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.

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.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jun 2 '07 #17

P: n/a
In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>I have no idea what ACM-ICPC is.
Association for Computing Machinary, International C Programming Contest?
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
Jun 2 '07 #18

P: n/a
ro******@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>>I have no idea what ACM-ICPC is.

Association for Computing Machinary, International C Programming Contest?
ACM International Collegiate Programming Contest.
<http://icpc.baylor.edu/icpc/>

I have no idea why this implies that one can't use fgets and fgetc.

--
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"
Jun 2 '07 #19

P: n/a
"Army1987" <pl********@for.itwrites:
"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com...
[...]
>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.)

--
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"
Jun 2 '07 #20

P: n/a
On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987"
<pl********@for.itwrote:
>
"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com.. .
>On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
<ka******@gmail.comwrote:
>>>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.

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
Jun 2 '07 #21

P: n/a
Keith Thompson wrote:
>
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.

--
Tor <torust [at] online [dot] no>
Jun 2 '07 #22

P: n/a
Mark McIntyre wrote:
On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987"
<pl********@for.itwrote:
>"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com.. .
>>On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
<ka******@gmail.comwrote:

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.
A little too extreme...

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.

--
Tor <torust [at] online [dot] no>
Jun 3 '07 #23

P: n/a
Tor Rustad <to********@hotmail.comwrites:
Mark McIntyre wrote:
>On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987"
<pl********@for.itwrote:
>>"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com. ..
On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
<ka******@gmail.comwrote:

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.
A little too extreme...

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.
And the input stream might be via a pipe with guaranteed input data integrity.
Jun 3 '07 #24

P: n/a
Tor Rustad <to********@hotmail.comwrites:
Keith Thompson wrote:
>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".
Easily, if the input string represents a number outside the range of
the target type.
Of course, I assume there is no type mismatch... between conversion
specifiers and object.
#include <stdio.h>
#include <limits.h>
#include <string.h>
int main(void)
{
#define BIG_ENOUGH 100
char buf[BIG_ENOUGH];
long n = 0;
int result;

sprintf(buf, "%ld", LONG_MAX);
memset(buf, '9', strlen(buf));

printf("LONG_MAX = %ld\n", LONG_MAX);
printf("buf = \"%s\"\n", buf);

result = sscanf(buf, "%li", &n);
if (result == 1) {
printf("n = %ld\n", n);
}
else {
printf("n = %ld (may not be meaningful)\n", n);
}
printf("sscanf() returned %d\n", result);

return 0;
}

I get the following results on various systems (all of which are
valid, since the behavior is undefined):

LONG_MAX = 2147483647
buf = "9999999999"
n = 2147483647
sscanf() returned 1

LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 9223372036854775807
sscanf() returned 1

LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = -8446744073709551617
sscanf() returned 1

LONG_MAX = 2147483647
buf = "9999999999"
n = 1410065407
sscanf() returned 1

LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 0 (may not be meaningful)
sscanf() returned -1

--
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"
Jun 3 '07 #25

P: n/a
>On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak
><ka******@gmail.comwrote:
>>>But how can I avoid [various problems with scanf]?
>"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com.. .
>Don't use scanf.
In article <f3*********@tdi.cu.mi.itArmy1987 <pl********@for.itwrote:
>A little too extreme...
Not in general. Maybe in some specific, well-controlled cases. :-)
>For example:

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

As someone (I think Keith Thompson) pointed out, this can misbehave
(formally, has "undefined behavior") if someone enters an overlarge
number. Your second variant (using %ld and a "long") still suffers
from this problem. (In practice, real implementations almost always
do at least one of these things: use strtol() internally, thus
clamping out of range inputs; use atoi() or atol() internally,
often behaving annoyingly but predictably by "wrapping" out of
range inputs based on the machine's internal representation; or
discover -- in some cases based solely on input length, and thus
sometimes having trouble with leading zeros -- that the value would
have been out of range, and stop the scanf engine with a matching
failure.)

More practically, this code is rather "user-unfriendly" when the
scanf() occurs after a recent prompt:

printf("enter a number: ");
fflush(stdout);
/* your loop using scanf() here */

If the user types nothing but a carriage return, the computer
simply sits there, having accepted the input line, waiting for
more input -- but without producing any diagnostic output like:
puts("Please enter an integer");
or repeating the prompt or anything. The scanf() call is still
running, waiting for more input, since "%d" skips leading white
space, and an empty line is "white space".

The rule that beginners should never use scanf() is, I think, a
good one. (To gain experience with the scanf family's behavior,
one can get input lines into buffers and apply sscanf(), then
inspect the subsequent wreckage. The buffers preserve the original
input and help insulate the program's "weird internal behavior due
to scanf" from its "obvious and immediate external I/O behavior".
In other words, the buffers ... well, they *buffer*:

buffer ... [as transitive verb] ... 12. to cushion, shield,
or protect. 13. to lessen the adverse effect of ...
-- from <http://dictionary.reference.com/browse/buffer>

The scanf() function is a lot like a field of cactus in bloom:
pretty, but it is dangerous to get too close. :-) )
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 3 '07 #26

P: n/a
Keith Thompson wrote:
Tor Rustad <to********@hotmail.comwrites:
>Keith Thompson wrote:
>>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".

Easily, if the input string represents a number outside the range of
the target type.
Thanks for your detailed answer Keith, do you perhaps also have a link
to comp.std.c, where this topic has been discussed?

When I read the C standard, I expected numerical overflow/underflow to
be a matching failure, if *not* underflow or overflow is *inappropriate
input*, what do we call such input then???

Indeed, TR 24731 clearly define this as a matching failure too, but the
scanf_s() family of functions, is just an extension.

If still accepting the input item, implementations *should* IMO give it
LONG_MAX/LONG_MIN value, so that the caller can detect the error condition.

When the "numerical" directive is processed, the valid range of
numerical input field is known apriori to the implementation, so IMO
there is no acceptable reason for implementations (or standard) to put
this into UB land.

C89 also state:

<quote>
The following conversion specifiers are valid:

d Matches an optionally signed decimal integer, whose format is the
same as expected for the subject sequence of the strtol function with
the value 10 for the base argument. The corresponding argument shall
be a pointer to integer.
</quote>

and since strtol() function very much detect underflow/overflow, I guess
more clever people than me, has been fooled by this too (e.g. I can't
remember Les Hattton in "Safer C" listing this case in his UB list).
<snip>

I get the following results on various systems (all of which are
valid, since the behavior is undefined):

LONG_MAX = 2147483647
buf = "9999999999"
n = 2147483647
sscanf() returned 1
If 1 is returned, overflow(/underflow) can still be detected by checking
LONG_MAX (or LONG_MIN)
LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 9223372036854775807
sscanf() returned 1
Also, ok.
LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = -8446744073709551617
sscanf() returned 1
Which C implementation is this?
LONG_MAX = 2147483647
buf = "9999999999"
n = 1410065407
sscanf() returned 1
Which C implementation is this?
LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 0 (may not be meaningful)
sscanf() returned -1
Did scanf return EOF? It is not a input failure in my view.

--
Tor <torust [at] online [dot] no>
Jun 3 '07 #27

P: n/a

"Keith Thompson" <ks***@mib.orgha scritto nel messaggio
news:ln************@nuthaus.mib.org...
"Army1987" <pl********@for.itwrites:
>"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com.. .
[...]
>>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.
Yes, but, two paragraphs below:
d Matches an optionally signed decimal integer, whose format is the same as
expected for the subject sequence of the strtol function with the value 10
for the base argument. The corresponding argument shall be a pointer to
signed integer.

7.20.1.4p8:
The strtol, strtoll, strtoul, and strtoull functions return the converted
value, if any. If no conversion could be performed, zero is returned. If the
correct value is outside the range of representable values, LONG_MIN,
LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned
(according to the return type and sign of the value, if any), and the value
of the macro ERANGE is stored in errno.

So apparently the condition you're mentioning only can happen with
int or narrower types. If my interpretation of the Standard is
correct, with long the worst that can happen is that tmp becomes
LONG_MAX or LONG_MIN and errno becomes ERANGE. (But I would not be
that sure, since "whose format is the same as expected for the
subject sequence of the strtol function with the value 10 for the
base argument" doesn't clearly state that the result will be the
same, too. But then, there is nothing to guarantee that the
sequence "12345" isn't converted to the int -23.)
Jun 3 '07 #28

P: n/a

"Chris Torek" <no****@torek.netha scritto nel messaggio
news:f3*********@news2.newsguy.com...
More practically, this code is rather "user-unfriendly" when the
scanf() occurs after a recent prompt:

printf("enter a number: ");
fflush(stdout);
/* your loop using scanf() here */

If the user types nothing but a carriage return, the computer
simply sits there, having accepted the input line, waiting for
more input -- but without producing any diagnostic output like:
> puts("Please enter an integer");

or repeating the prompt or anything. The scanf() call is still
running, waiting for more input, since "%d" skips leading white
space, and an empty line is "white space".
At which point, the user simplily enters the number and re-hits
enter, and the programs goes on correctly. Unless the user thinks
that simplily hitting enter means the program should read their
mind.
Jun 3 '07 #29

P: n/a
Tor Rustad <to********@hotmail.comwrites:
[...]
Thanks for your detailed answer Keith, do you perhaps also have a link
to comp.std.c, where this topic has been discussed?
No, I don't recall it being discussed there (which is no indication
that it hasn't been discussed).
When I read the C standard, I expected numerical overflow/underflow to
be a matching failure, if *not* underflow or overflow is
*inappropriate input*, what do we call such input then???
Really? C99 7.19.6.2 seems very clear to me:

... the input item ... is converted to a type appropriate to the
conversion specifier. ... if the result of the conversion cannot
be represented in the object, the behavior is undefined.

Note that it doesn't specify how the conversion is performed.

[...]
If still accepting the input item, implementations *should* IMO give
it LONG_MAX/LONG_MIN value, so that the caller can detect the error
condition.
How could the caller distinguish between an overflow and a valid input
that happens to yield the value LONG_MAX or LONG_MIN?
When the "numerical" directive is processed, the valid range of
numerical input field is known apriori to the implementation, so IMO
there is no acceptable reason for implementations (or standard) to put
this into UB land.
I agree, but the standard permits it.

A naive implementation could perform the conversion (e.g., repeatedly
multiplying by 10 and adding the value of the next digit) without
concern for numeric overflow. If a numeric overflow occurs (for a
signed or floating-poit type), the behavior is undefined. I don't
think the standard *should* permit such an implementation, but it eems
clear that it does.
C89 also state:

<quote>
The following conversion specifiers are valid:

d Matches an optionally signed decimal integer, whose format is the
same as expected for the subject sequence of the strtol function with
the value 10 for the base argument. The corresponding argument shall
be a pointer to integer.
</quote>

and since strtol() function very much detect underflow/overflow, I
guess more clever people than me, has been fooled by this too (e.g. I
can't remember Les Hattton in "Safer C" listing this case in his UB
list).
I note that the C99 standard says (7.19.6.2p12) that "%d"

Matches an optionally signed decimal integer, whose format is the
same as expected for the subject sequence of the strtol function
with the value 10 for the base argument. The corresponding
argument shall be a pointer to signed integer.

This merely describes the *format* of the input, not the manner in
which the conversion is performed. In particular, note that strtol()
would not work for "%lld" (type long long), but the format is the
same. I think the reference to strtol is merely intended to avoid
repeating the description of the format.
>I get the following results on various systems (all of which are
valid, since the behavior is undefined):
LONG_MAX = 2147483647
buf = "9999999999"
n = 2147483647
sscanf() returned 1

If 1 is returned, overflow(/underflow) can still be detected by
checking LONG_MAX (or LONG_MIN)
No, it doesn't distinguish between an overflow and an actual input of
"2147483647".
>LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 9223372036854775807
sscanf() returned 1

Also, ok.
See above.
>LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = -8446744073709551617
sscanf() returned 1

Which C implementation is this?
I got that on Solaris and AIX in 64-bit mode.
>LONG_MAX = 2147483647
buf = "9999999999"
n = 1410065407
sscanf() returned 1

Which C implementation is this?
Solaris and AIX, both in 32-bit mode.
>LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 0 (may not be meaningful)
sscanf() returned -1

Did scanf return EOF? It is not a input failure in my view.
That's from an Alpha OSF1 system. Yes, scanf() returned EOF (scanf()
and sscanf behave the same way, and EOF == -1).

I think that treating it as an input failure is the most sensible
solution. It would be nice if there were a way to distinguish
different kinds of input failure (numeric overflow or underflow vs.
something that's not in the right format), but that would complicate
the interface.

--
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"
Jun 3 '07 #30

P: n/a
"Army1987" <pl********@for.itwrites:
"Keith Thompson" <ks***@mib.orgha scritto nel messaggio
news:ln************@nuthaus.mib.org...
>"Army1987" <pl********@for.itwrites:
>>"Mark McIntyre" <ma**********@spamcop.netha scritto nel messaggio
news:hm********************************@4ax.com. ..
[...]
>>>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.

Yes, but, two paragraphs below:
d Matches an optionally signed decimal integer, whose format is the same as
expected for the subject sequence of the strtol function with the value 10
for the base argument. The corresponding argument shall be a pointer to
signed integer.
Yes, it says the *format* is the same as expected by the strtol
function. It doesn't say that it uses the strtol function or
equivalent to do the conversion.

As I mentioned elsethread, strtol only handles type long; "%lld" would
require using strtoll. The strol function is mentioned only to
specify the format, not the algorithm. Likewise, the description of
%a, %e, %f, and %g mentions strtod, which doesn't handle long double.
If the standard intends to specify how the conversions are performed,
it doesn't do a very good job of it.
7.20.1.4p8:
The strtol, strtoll, strtoul, and strtoull functions return the converted
value, if any. If no conversion could be performed, zero is returned. If the
correct value is outside the range of representable values, LONG_MIN,
LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned
(according to the return type and sign of the value, if any), and the value
of the macro ERANGE is stored in errno.

So apparently the condition you're mentioning only can happen with
int or narrower types. If my interpretation of the Standard is
correct, with long the worst that can happen is that tmp becomes
LONG_MAX or LONG_MIN and errno becomes ERANGE. (But I would not be
that sure, since "whose format is the same as expected for the
subject sequence of the strtol function with the value 10 for the
base argument" doesn't clearly state that the result will be the
same, too. But then, there is nothing to guarantee that the
sequence "12345" isn't converted to the int -23.)
I don't agree with your interpretation. As far as I can tell, the
standard doesn't say *how* the conversion is performed. And the
statement of undefined behavior in C99 7.19.6.2p10 seems clear and
unambiguous.

--
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"
Jun 3 '07 #31

P: n/a
Army1987 wrote:
>
.... snip ...
>
d Matches an optionally signed decimal integer, whose format is
the same as expected for the subject sequence of the strtol function
with the value 10 for the base argument. The corresponding argument
shall be a pointer to signed integer.
This is really about i/o routines. Take a look at the code below
(partial, but useful):

/* ------------------------------------------------- *
* File txtinput.c *
* ------------------------------------------------- */

#include <limits.h /* xxxx_MAX, xxxx_MIN */
#include <ctype.h /* isdigit, isblank, isspace */
#include <stdio.h /* FILE, getc, ungetc */
#include "txtinput.h"

/* For licensing restrictions (GPL) see readme.txt in:
* <http://cbfalconer.home.att.net/download/txtio.zip>
*
* These stream input routines are written so that simple
* conditionals can be used:
*
* if (readxint(&myint, stdin)) {
* do_error_recovery; normally_abort_to_somewhere;
* }
* else {
* do_normal_things; usually_much_longer_than_bad_case;
* }
*
* They allow overflow detection, and permit other routines to
* detect the character that terminated a numerical field. No
* string storage is required, thus there is no limitation on
* the length of input fields. For example, a number entered
* with a string of 1000 leading zeroes will not annoy these.
*
* The numerical input routines *NEVER* absorb a terminating
* char (including '\n'). Thus a sequence such as:
*
* err = readxint(&myint, stdin);
* flushln(stdin);
*
* will always consume complete lines, and after execution of
* readxint a further getc (or fgetc) will return the character
* that terminated the numeric field.
*
* They are also re-entrant, subject to the limitations of file
* systems. e.g interrupting readxint(v, stdin) operation with
* a call to readxwd(wd, stdin) would not be well defined, if
* the same stdin is being used for both calls. If ungetc is
* interruptible the run-time system is broken.
*
* Originally issued 2002-10-07
*
* Revised 2006-01-15 so that unsigned entry overflow (readxwd)
uses the normal C modulo (UINT_MAX + 1) operation. readxwd
still rejects an initial sign as an error.
*/

/* -------------------------------------------------------------
* Skip to non-blank on f, and return that char. or EOF The next
* char that getc(f) will return is unknown. Local use only.
*/
static int ignoreblks(FILE *f)
{
int ch;

do {
ch = getc(f);
} while ((' ' == ch) || ('\t' == ch));
/* while (isblank(ch)); */ /* for C99 */
return ch;
} /* ignoreblks */

/*--------------------------------------------------------------
* Skip all blanks on f. At completion getc(f) will return
* a non-blank character, which may be \n or EOF
*
* Skipblks returns the char that getc will next return, or EOF.
*/
int skipblks(FILE *f)
{
return ungetc(ignoreblks(f), f);
} /* skipblks */

/*--------------------------------------------------------------
* Skip all whitespace on f, including \n, \f, \v, \r. At
* completion getc(f) will return a non-blank character, which
* may be EOF
*
* Skipwhite returns the char that getc will next return, or EOF.
*/
int skipwhite(FILE *f)
{
int ch;

do {
ch = getc(f);
} while (isspace(ch));
return ungetc(ch, f);
} /* skipwhite */

/*--------------------------------------------------------------
* Read an unsigned value. Signal error for overflow or no
* valid number found. Returns 1 for error, 0 for noerror, EOF
* for EOF encountered before parsing a value.
*
* Skip all leading blanks on f. At completion getc(f) will
* return the character terminating the number, which may be \n
* or EOF among others. Barring EOF it will NOT be a digit. The
* combination of error, 0 result, and the next getc returning
* \n indicates that no numerical value was found on the line.
*
* If the user wants to skip all leading white space including
* \n, \f, \v, \r, he should first call "skipwhite(f);"
*
* Peculiarity: This specifically forbids a leading '+' or '-'.
*/
int readxwd(unsigned int *wd, FILE *f)
{
unsigned int value, digit;
int status;
int ch;

#define UWARNLVL (UINT_MAX / 10U)
#define UWARNDIG (UINT_MAX - UWARNLVL * 10U)

value = 0; /* default */
status = 1; /* default error */

ch = ignoreblks(f);

if (EOF == ch) status = EOF;
else if (isdigit(ch)) status = 0; /* digit, no error */

while (isdigit(ch)) {
digit = ch - '0';
if ((value UWARNLVL) ||
((UWARNLVL == value) && (digit UWARNDIG))) {
status = 1; /* overflow */
value -= UWARNLVL;
}
value = 10 * value + digit;
ch = getc(f);
} /* while (ch is a digit) */

*wd = value;
ungetc(ch, f);
return status;
} /* readxwd */

Further routines eliminated.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 4 '07 #32

P: n/a
Tak
On 6 3 , 2 36 , Keith Thompson <k...@mib.orgwrote:
rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <4661A583.FD124...@yahoo.com>,
CBFalconer <cbfalco...@maineline.netwrote:
>I have no idea what ACM-ICPC is.
Association for Computing Machinary, International C Programming Contest?

ACM International Collegiate Programming Contest.
<http://icpc.baylor.edu/icpc/>

I have no idea why this implies that one can't use fgets and fgetc.
I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?

Jun 4 '07 #33

P: n/a
Keith Thompson wrote:
Tor Rustad <to********@hotmail.comwrites:
[...]
>When I read the C standard, I expected numerical overflow/underflow to
be a matching failure, if *not* underflow or overflow is
*inappropriate input*, what do we call such input then???

Really? C99 7.19.6.2 seems very clear to me:
I wasn't really arguing my case here, I did accept that your
interpretation was correct, after your previous post. However,

>If still accepting the input item, implementations *should* IMO give
it LONG_MAX/LONG_MIN value, so that the caller can detect the error
condition.

How could the caller distinguish between an overflow and a valid input
that happens to yield the value LONG_MAX or LONG_MIN?
By defining the valid range of input item 'x' as e.g. LONG_MIN < x <
LONG_MAX, which is no great loss in practice.

The alternative, is to specify field, like we do for %s, which is not
exactly an attractive solution.
>>LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = -8446744073709551617
sscanf() returned 1
Which C implementation is this?

I got that on Solaris and AIX in 64-bit mode.
I was surprised it was Solaris and AIX.

>>LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 0 (may not be meaningful)
sscanf() returned -1
Did scanf return EOF? It is not a input failure in my view.

That's from an Alpha OSF1 system. Yes, scanf() returned EOF (scanf()
and sscanf behave the same way, and EOF == -1).

I think that treating it as an input failure is the most sensible
solution. It would be nice if there were a way to distinguish
different kinds of input failure (numeric overflow or underflow vs.
something that's not in the right format), but that would complicate
the interface.


--
Tor <torust [at] online [dot] no>
Jun 4 '07 #34

P: n/a
Tor Rustad wrote:

[Sorry, misclick and prev post slipped away, before I was finished
editing my reply]
>>>LONG_MAX = 9223372036854775807
buf = "9999999999999999999"
n = 0 (may not be meaningful)
sscanf() returned -1
Did scanf return EOF? It is not a input failure in my view.

That's from an Alpha OSF1 system. Yes, scanf() returned EOF (scanf()
and sscanf behave the same way, and EOF == -1).

I think that treating it as an input failure is the most sensible
solution. It would be nice if there were a way to distinguish
different kinds of input failure (numeric overflow or underflow vs.
something that's not in the right format), but that would complicate
the interface.
C89 wording was:

<quote>
The fscanf function executes each directive of the format in turn.
If a directive fails, as detailed below, the fscanf function returns.
Failures are described as input failures (due to the unavailability of
input characters), or matching failures (due to inappropriate input).
[...]
An input item is read from the stream, unless the specification
includes an n specifier. An input item is defined as the longest
sequence of input characters (up to any specified maximum field width)
which is an initial subsequence of a matching sequence. The first
character, if any, after the input item remains unread. If the length
of the input item is zero, the execution of the directive fails: this
condition is a matching failure, unless an error prevented input from
the stream, in which case it is an input failure.
</quote>

Hence, an input error is "unavailability of input characters", which
isn't exactly what a numerical overflow/underflow is in this context,
quite the opposite...
--
Tor <torust [at] online [dot] no>
Jun 4 '07 #35

P: n/a
Tak <ka******@gmail.comwrites:
On 6 3 , 2 36 , Keith Thompson <k...@mib.orgwrote:
>rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:
In article <4661A583.FD124...@yahoo.com>,
CBFalconer <cbfalco...@maineline.netwrote:
I have no idea what ACM-ICPC is.
Association for Computing Machinary, International C Programming Contest?

ACM International Collegiate Programming Contest.
<http://icpc.baylor.edu/icpc/>

I have no idea why this implies that one can't use fgets and fgetc.

I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?
You wrote:

I solve problems from ACM-ICPC, so fgets fgetc are not useful.

which implies that you can't use fgets and fgetc *because* you're
solving problems from ACM-ICPC. Now it looks like that has nothing to
do with your problem.

Saying that you get a "Wrong Answer" doesn't tell us anything. If
you'll show us some sample code, perhaps we can help you figure out
why fgets and fgetc aren't working. There's no reason they shouldn't
work if you use them properly.

--
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"
Jun 4 '07 #36

P: n/a
Tor Rustad <to********@hotmail.comwrites:
Keith Thompson wrote:
>Tor Rustad <to********@hotmail.comwrites:
[...]
>>If still accepting the input item, implementations *should* IMO give
it LONG_MAX/LONG_MIN value, so that the caller can detect the error
condition.
How could the caller distinguish between an overflow and a valid
input
that happens to yield the value LONG_MAX or LONG_MIN?

By defining the valid range of input item 'x' as e.g. LONG_MIN < x <
LONG_MAX, which is no great loss in practice.
I disagree. Reserving a value as an error indicator, such as EOF for
fgetc or NULL for malloc, is sensible when that value can't also be a
valid result. Reserving a value that could be valid limits the
usefulness of the interface. Whether this is a significant loss
depends on the application.
The alternative, is to specify field, like we do for %s, which is not
exactly an attractive solution.
IMHO, a better alternative given the current interface is to treat
overflow as a matching error. It would be even better to be able to
distinguish between overflow and non-numeric input, but IMHO that's
not as important. The *scanf functions can't be expected to provide a
universal solution for parsing arbitrary input; if you need something
more sophisticated, you can write it yourself.

--
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"
Jun 4 '07 #37

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Tor Rustad <to********@hotmail.comwrites:
[...]
>Thanks for your detailed answer Keith, do you perhaps also have a link
to comp.std.c, where this topic has been discussed?

No, I don't recall it being discussed there (which is no indication
that it hasn't been discussed).
I started a thread on comp.std.c, subject
Undefined behavior for *scanf with "%d"

--
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"
Jun 4 '07 #38

P: n/a
Keith Thompson wrote On 06/04/07 04:28,:
Tak <ka******@gmail.comwrites:
>>On 6 3 , 2 36 , Keith Thompson <k...@mib.orgwrote:
>>>rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson) writes:

In article <4661A583.FD124...@yahoo.com>,
CBFalconer <cbfalco...@maineline.netwrote:

>I have no idea what ACM-ICPC is.

Association for Computing Machinary, International C Programming Contest?

ACM International Collegiate Programming Contest.
<http://icpc.baylor.edu/icpc/>

I have no idea why this implies that one can't use fgets and fgetc.

I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?


You wrote:

I solve problems from ACM-ICPC, so fgets fgetc are not useful.

which implies that you can't use fgets and fgetc *because* you're
solving problems from ACM-ICPC. Now it looks like that has nothing to
do with your problem.

Saying that you get a "Wrong Answer" doesn't tell us anything. If
you'll show us some sample code, perhaps we can help you figure out
why fgets and fgetc aren't working. There's no reason they shouldn't
work if you use them properly.
Keep in mind that the O.P. is engaged in a programming
contest. Try to offer help in a form that will require his
entry to involve a substantial portion of his own work.

(He's up-front about the matter, not like those scum
who want their homework done for them. As such, I feel
he deserves help, not abuse -- but let's remain aware of
the context, shall we?)

--
Er*********@sun.com

Jun 4 '07 #39

P: n/a
In article <11*********************@d30g2000prg.googlegroups. com>,
Tak <ka******@gmail.comwrote:
>On 6 3 , 2 36 , Keith Thompson <k...@mib.orgwrote:
>ACM International Collegiate Programming Contest.
>I have no idea why this implies that one can't use fgets and fgetc.
>I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?
Your response hints to me that you did not use fgets() or fgetc()
properly. The standard C library does not operate on "files", it
operates on "streams". It is entirely possible with C that one
run of a program will have a stream attached to a file and the
next run with the stream attached to a terminal, without any changes
in the code.

The key to using fgets() or fgetc() with the standard input stream
is to supply the FILE* parameter as the name stdin such as

if ( fgets(&mybuffer, sizeof mybuffer, stdin) != NULL ) { ... }

--
There are some ideas so wrong that only a very intelligent person
could believe in them. -- George Orwell
Jun 4 '07 #40

P: n/a
Walter Roberson wrote:
>
In article <11*********************@d30g2000prg.googlegroups. com>,
Tak <ka******@gmail.comwrote:
On 6 3 , 2 36 , Keith Thompson <k...@mib.orgwrote:
ACM International Collegiate Programming Contest.
I have no idea why this implies that one can't use fgets and fgetc.
I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?

Your response hints to me that you did not use fgets() or fgetc()
properly.
There's always a way to use fgetc.
N869
7.19.3 Files
[#11]
The byte input functions
read characters from the stream as if by successive calls to
the fgetc function.
The standard C library does not operate on "files", it
operates on "streams". It is entirely possible with C that one
run of a program will have a stream attached to a file and the
next run with the stream attached to a terminal, without any changes
in the code.

The key to using fgets() or fgetc() with the standard input stream
is to supply the FILE* parameter as the name stdin such as

if ( fgets(&mybuffer, sizeof mybuffer, stdin) != NULL ) { ... }
--
pete
Jun 4 '07 #41

P: n/a
Keith Thompson wrote:
Tor Rustad <to********@hotmail.comwrites:
>Keith Thompson wrote:
>>Tor Rustad <to********@hotmail.comwrites:
[...]
>>>If still accepting the input item, implementations *should* IMO give
it LONG_MAX/LONG_MIN value, so that the caller can detect the error
condition.
How could the caller distinguish between an overflow and a valid
input
that happens to yield the value LONG_MAX or LONG_MIN?
By defining the valid range of input item 'x' as e.g. LONG_MIN < x <
LONG_MAX, which is no great loss in practice.

I disagree. Reserving a value as an error indicator, such as EOF for
fgetc or NULL for malloc, is sensible when that value can't also be a
valid result. Reserving a value that could be valid limits the
usefulness of the interface. Whether this is a significant loss
depends on the application.
My point is that this is better than having UB, so if an implementation
"must" accept the input item, well then the first two implementations of
the ones you tested, did the best alternative in my view (i.e. Solaris
and AIX did the worst thing).

>The alternative, is to specify field, like we do for %s, which is not
exactly an attractive solution.

IMHO, a better alternative given the current interface is to treat
overflow as a matching error. It would be even better to be able to
distinguish between overflow and non-numeric input, but IMHO that's
not as important. The *scanf functions can't be expected to provide a
universal solution for parsing arbitrary input; if you need something
more sophisticated, you can write it yourself.
We do agree do on this, and this was how I beleaved the intent of the
C89 standard was. After a matching error has been detected, errno could
be set to indicate reason for the failure.

PS. I did check "The Single UNIX Specification, Version 2", if the
overflow/underflow case was addressed there, without any success.

--
Tor <torust [at] online [dot] no>
Jun 4 '07 #42

P: n/a
Keith Thompson wrote:
Keith Thompson <ks***@mib.orgwrites:
>Tor Rustad <to********@hotmail.comwrites:
[...]
>>Thanks for your detailed answer Keith, do you perhaps also have a link
to comp.std.c, where this topic has been discussed?
No, I don't recall it being discussed there (which is no indication
that it hasn't been discussed).

I started a thread on comp.std.c, subject
Undefined behavior for *scanf with "%d"
Excellent! Perhaps P.J. Plauger will make a comment on if TR 24731 (Part
I: Bounds-checking interfaces) intentionally identified this as a
matching failure.

--
Tor <torust [at] online [dot] no>
Jun 4 '07 #43

P: n/a
Tor Rustad wrote:
Keith Thompson wrote:
>Keith Thompson <ks***@mib.orgwrites:
>>Tor Rustad <to********@hotmail.comwrites:
[...]
Thanks for your detailed answer Keith, do you perhaps also have a link
to comp.std.c, where this topic has been discussed?
No, I don't recall it being discussed there (which is no indication
that it hasn't been discussed).

I started a thread on comp.std.c, subject
Undefined behavior for *scanf with "%d"

Excellent! Perhaps P.J. Plauger will make a comment on if TR 24731 (Part
I: Bounds-checking interfaces) intentionally identified this as a
matching failure.
When I checked the latest draft of TR 24731, it is clear that they don't
include numerical overflow/underflow as a matching failure after all.

<quote>
fscanf_s function is equivalent to fscanf except that the c, s and [
conversion...
</quote>

Sorry!

--
Tor <torust [at] online [dot] no>
Jun 4 '07 #44

P: n/a
On Jun 2, 10:17 am, CBFalconer <cbfalco...@yahoo.comwrote:
Walter Roberson wrote:
while ( (c = getchar()) != EOF && c == '\n' )
{ /* empty loop body */ }
^^
{should be !=) :-)
The original was correct; the purpose of the code
is to consume '\n' characters.

Jun 4 '07 #45

P: n/a
In article <11**********************@d30g2000prg.googlegroups .com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>On Jun 2, 10:17 am, CBFalconer <cbfalco...@yahoo.comwrote:
>Walter Roberson wrote:
while ( (c = getchar()) != EOF && c == '\n' )
{ /* empty loop body */ }
^^
{should be !=) :-)
>The original was correct; the purpose of the code
is to consume '\n' characters.
Exactly -- and my posting specifically indicated that as the
intended behaviour.

--
If you lie to the compiler, it will get its revenge. -- Henry Spencer
Jun 4 '07 #46

P: n/a
Tak
On 64, 11ʱ33, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?

Your response hints to me that you did not use fgets() or fgetc()
properly. The standard C library does not operate on "files", it
operates on "streams". It is entirely possible with C that one
run of a program will have a stream attached to a file and the
next run with the stream attached to a terminal, without any changes
in the code.

The key to using fgets() or fgetc() with the standard input stream
is to supply the FILE* parameter as the name stdin such as

if ( fgets(&mybuffer, sizeof mybuffer, stdin) != NULL ) { ... }
can you tell me how to deal with this "a+b problem" by /fgets/ in your
format?
P.S.
it's not homework.
the a+b problem:
Input:
The input will consist of a series of pairs of integers a and
b,separated by a space, one pair of integers per line.
Output:
For each pair of input integers a and b you should output the sum of a
and b in one line,and with one line of output for each line in input.

Jun 5 '07 #47

P: n/a
Tak wrote, On 05/06/07 11:05:
On 64, 11ʱ33, rober...@ibd.nrc-cnrc.gc.ca (Walter Roberson)
wrote:
>>I don't know.when I use fgets,fgetc the system return me a Wrong
Answer. Maybe because the test data is not stored in a file,so we
can't use fgets,fgetc to get data?
Your response hints to me that you did not use fgets() or fgetc()
properly. The standard C library does not operate on "files", it
operates on "streams". It is entirely possible with C that one
run of a program will have a stream attached to a file and the
next run with the stream attached to a terminal, without any changes
in the code.

The key to using fgets() or fgetc() with the standard input stream
is to supply the FILE* parameter as the name stdin such as

if ( fgets(&mybuffer, sizeof mybuffer, stdin) != NULL ) { ... }
can you tell me how to deal with this "a+b problem" by /fgets/ in your
format?
P.S.
it's not homework.
You've still not attempted it though.
the a+b problem:
Input:
The input will consist of a series of pairs of integers a and
b,separated by a space, one pair of integers per line.
Output:
For each pair of input integers a and b you should output the sum of a
and b in one line,and with one line of output for each line in input.
Parse the lines with the parser of your choice, strtol for example, sum
the data and output it. Nothing difficult. If you want serious help make
a serious attempt yourself and post it.
--
Flash Gordon
Jun 5 '07 #48

P: n/a
Tak wrote:
>
.... snip ...
>
can you tell me how to deal with this "a+b problem" by /fgets/ in
your format?

it's not homework. the a+b problem:
Input:
The input will consist of a series of pairs of integers a and
b,separated by a space, one pair of integers per line.

Output:
For each pair of input integers a and b you should output the sum
of a and b in one line,and with one line of output for each line
in input.
The input is in text form. You have to convert that to integers
before adding. Then you convert the result back into text. The
first phase can be handled by scanf, or (fgets or ggets) and
(sscanf or strtod or strtoul). The second by printf. Read up on
what those functions do. The prefereable place to read is the C
standard. ggets is non-standard, available on my page.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Jun 6 '07 #49

P: n/a

"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.caha scritto nel messaggio
news:f4**********@canopus.cc.umanitoba.ca...
In article <11**********************@d30g2000prg.googlegroups .com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>>On Jun 2, 10:17 am, CBFalconer <cbfalco...@yahoo.comwrote:
>>Walter Roberson wrote:
>while ( (c = getchar()) != EOF && c == '\n' )
{ /* empty loop body */ }
^^
{should be !=) :-)
>>The original was correct; the purpose of the code
is to consume '\n' characters.

Exactly -- and my posting specifically indicated that as the
intended behaviour.
Since '\n' != EOF, couldn't you just write
while (getchar() == '\n)
continue;
?
Jun 8 '07 #50

98 Replies

This discussion thread is closed

Replies have been disabled for this discussion.