|
|
 |
 |
 |
 |
Puzzle!
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?
On 6 2 , 1 15 , Tak <kakat@gmail.com> wrote: > 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; > }
In article <1180718112.979701.75@i13g2000prf.googlegroups.com>, Tak <kakat @gmail.com> wrote: >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
Tak <kakat @gmail.com> writes: > 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) k@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"
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
On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak <kakat @gmail.com> wrote: >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
On 6 2 , 7 26 , Mark McIntyre <markmcint@spamcop.net> wrote: > On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak > <kakat@gmail.com> wrote: > >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?
"Mark McIntyre" <markmcint@spamcop.net> ha scritto nel messaggio news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com... > On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak > <kakat @gmail.com> wrote: >>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);
Tak wrote, On 02/06/07 04:31: > On 6 2 , 7 26 , Mark McIntyre <markmcint @spamcop.net> wrote: >> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak >> <kakat@gmail.com> wrote: >>> 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
On 6 2 , 3 58 , "Army1987" <please.@for.it> wrote: I've learnt that statement /scanf("%[^.]", str); /is usually dangerous in some conditions.
On 6 2 , 3 39 , Flash Gordon <s@flash-gordon.me.uk> wrote: > Tak wrote, On 02/06/07 04:31: > > On 6 2 , 7 26 , Mark McIntyre <markmcint@spamcop.net> wrote: > >> 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;
}
Tak wrote: > On 6 2 , 3 58 , "Army1987" <please. @for.it> wrote: >> "Mark McIntyre" <markmcint @spamcop.net> ha scritto nel >> messaggio news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@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.
"Tak" <kakat@gmail.com> ha scritto nel messaggio news:1180773802.789151.42330@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?
On 6 2 , 7 21 , "Army1987" <please.@for.it> wrote:
> "Tak" <kakat @gmail.com> ha scritto nel messaggio news:1180773802.789151.42330@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.
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
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
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.
In article <4661A583.FD124@yahoo.com>, CBFalconer <cbfalco @maineline.net> wrote: >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
rober @ibd.nrc-cnrc.gc.ca (Walter Roberson) writes: > In article <4661A583.FD124 @yahoo.com>, > CBFalconer <cbfalco @maineline.net> wrote: >>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) k@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"
"Army1987" <please. @for.it> writes: > "Mark McIntyre" <markmcint @spamcop.net> ha scritto nel messaggio > news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@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) k@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"
On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987"
<please. @for.it> wrote: >"Mark McIntyre" <markmcint@spamcop.net> ha scritto nel messaggio >news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com... >> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak >> <kakat@gmail.com> wrote: >>>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
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>
Mark McIntyre wrote: > On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987" > <please. @for.it> wrote: >> "Mark McIntyre" <markmcint@spamcop.net> ha scritto nel messaggio >> news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com... >>> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak >>> <kakat@gmail.com> wrote: >>>> 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>
Tor Rustad <tor_rus @hotmail.com> writes: > Mark McIntyre wrote: >> On Sat, 2 Jun 2007 09:58:26 +0200, in comp.lang.c , "Army1987" >> <please. @for.it> wrote: >>> "Mark McIntyre" <markmcint@spamcop.net> ha scritto nel messaggio >>> news:hma163d8u8t50m0rqrpcem1lcobheh4l5r@4ax.com... >>>> On Fri, 01 Jun 2007 17:15:12 -0000, in comp.lang.c , Tak >>>> <kakat@gmail.com> wrote: >>>>> 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.
Tor Rustad <tor_rus @hotmail.com> writes: > 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) k@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"
|
 |
 |
 |
 |
|