From: Felix V. <alp...@ho...> - 2006-07-20 22:32:47
|
Alas, I thought the problem was resolved, but no, it reoccurs: [test.c file]: #include <stdio.h> int main() { char a,b,c,d; int e,f,g,h; printf("start"); e=fscanf(stdin,"%c",&a); f=fscanf(stdin,"%c",&b); g=fscanf(stdin,"%c",&c); h=fscanf(stdin,"%c",&d); printf("\n\n\"%c%c%c%c\"=character input\n",a,b,c,d); printf("%d%d%d%d=fscanf output",e,f,g,h); } [entered into command prompt]: C:\MinGW>gcc test.c -o test.exe C:\MinGW>test.exe startu 6 "u 6"=character input 1111=fscanf output C:\MinGW>test.exe start " "=character input 1111=fscanf output [the actual characters entered for the first test are 'u','<return>','<space>', and '6'. For the second case the characters are all spaces.] [ I have tested this with scanf, gets, fgetc with similar arrangements and the results have been the same] [end] And that is my problem; I have been told that scanf() stops reading input when it encounters a space, but that appears not to be so here. As I said earlier, the scanf and gets functions only work every other time, I believe that is because when I hit the <return> key the <return> is automatically entered as the input to the next input function. ??? _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today - it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: Jeremy B. <je...@de...> - 2006-07-20 22:48:54
|
>From MSDN: %c: When used with scanf functions, specifies single-byte character; when used with wscanf functions, specifies wide character. White-space characters that are ordinarily skipped are read when c is specified. To read next non-white-space single-byte character, use %1s; to read next non-white-space wide character, use %1ws. So the program is correctly reading your text. It reads 'u' '\r' '\n' '6', and if you would have used %d in your printf statements you would have seen this. ----- Original Message ----- From: "Felix VIII" <alp...@ho...> To: <min...@li...> Sent: Thursday, July 20, 2006 5:32 PM Subject: [Mingw-users] scanf, fscanf, gets, fgetc,and mostly-every-other-input-function problem > Alas, I thought the problem was resolved, but no, it reoccurs: > > [test.c file]: > #include <stdio.h> > > int main() > { > char a,b,c,d; > int e,f,g,h; > printf("start"); > e=fscanf(stdin,"%c",&a); > f=fscanf(stdin,"%c",&b); > g=fscanf(stdin,"%c",&c); > h=fscanf(stdin,"%c",&d); > printf("\n\n\"%c%c%c%c\"=character input\n",a,b,c,d); > printf("%d%d%d%d=fscanf output",e,f,g,h); > } > > [entered into command prompt]: > C:\MinGW>gcc test.c -o test.exe > > C:\MinGW>test.exe > startu > 6 > > "u > 6"=character input > 1111=fscanf output > C:\MinGW>test.exe > start > > > " "=character input > 1111=fscanf output > [the actual characters entered for the first test are > 'u','<return>','<space>', and '6'. For the second case the characters are > all spaces.] > [ I have tested this with scanf, gets, fgetc with similar arrangements and > the results have been the same] > [end] > > And that is my problem; I have been told that scanf() stops reading input > when it encounters a space, but that appears not to be so here. As I said > earlier, the scanf and gets functions only work every other time, I > believe > that is because when I hit the <return> key the <return> is automatically > entered as the input to the next input function. > > ??? > > _________________________________________________________________ > Express yourself instantly with MSN Messenger! Download today - it's FREE! > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ > > > ------------------------------------------------------------------------- > Take Surveys. Earn Cash. Influence the Future of IT > Join SourceForge.net's Techsay panel and you'll get the chance to share > your > opinions on IT & business topics through brief surveys -- and earn cash > http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > _______________________________________________ > MinGW-users mailing list > Min...@li... > > You may change your MinGW Account Options or unsubscribe at: > https://lists.sourceforge.net/lists/listinfo/mingw-users > |
From: Felix V. <alp...@ho...> - 2006-07-20 23:07:54
|
For some reason when I use "%1s" it only reads the fourth character input (d): [test.c] #include <stdio.h> int main() { char a,b,c,d; int e,f,g,h; printf("start"); e=fscanf(stdin,"%1s",&a); f=fscanf(stdin,"%1s",&b); g=fscanf(stdin,"%1s",&c); h=fscanf(stdin,"%1s",&d); printf("\n\n\"%c%c%c%c\"=character input\n",a,b,c,d); printf("%d%d%d%d=fscanf output",e,f,g,h); } [command prompt test]: gcc test.c -o test.exe test.exe start abcd [entered 1 space and then 'a','b','c','d','<return>'] " d"=character input 1111=fscanf output >From: "Jeremy Bettis" <je...@de...> >Reply-To: MinGW Users List <min...@li...> >To: "MinGW Users List" <min...@li...> >Subject: Re: [Mingw-users] scanf, fscanf, gets, fgetc,and >mostly-every-other-input-function problem >Date: Thu, 20 Jul 2006 17:48:37 -0500 > > >From MSDN: >%c: When used with scanf functions, specifies single-byte character; when >used with wscanf functions, specifies wide character. White-space >characters >that are ordinarily skipped are read when c is specified. To read next >non-white-space single-byte character, use %1s; to read next >non-white-space >wide character, use %1ws. > >So the program is correctly reading your text. It reads 'u' '\r' '\n' '6', >and if you would have used %d in your printf statements you would have seen >this. > >----- Original Message ----- >From: "Felix VIII" <alp...@ho...> >To: <min...@li...> >Sent: Thursday, July 20, 2006 5:32 PM >Subject: [Mingw-users] scanf, fscanf, gets, fgetc,and >mostly-every-other-input-function problem > > > > Alas, I thought the problem was resolved, but no, it reoccurs: > > > > [test.c file]: > > #include <stdio.h> > > > > int main() > > { > > char a,b,c,d; > > int e,f,g,h; > > printf("start"); > > e=fscanf(stdin,"%c",&a); > > f=fscanf(stdin,"%c",&b); > > g=fscanf(stdin,"%c",&c); > > h=fscanf(stdin,"%c",&d); > > printf("\n\n\"%c%c%c%c\"=character input\n",a,b,c,d); > > printf("%d%d%d%d=fscanf output",e,f,g,h); > > } > > > > [entered into command prompt]: > > C:\MinGW>gcc test.c -o test.exe > > > > C:\MinGW>test.exe > > startu > > 6 > > > > "u > > 6"=character input > > 1111=fscanf output > > C:\MinGW>test.exe > > start > > > > > > " "=character input > > 1111=fscanf output > > [the actual characters entered for the first test are > > 'u','<return>','<space>', and '6'. For the second case the characters >are > > all spaces.] > > [ I have tested this with scanf, gets, fgetc with similar arrangements >and > > the results have been the same] > > [end] > > > > And that is my problem; I have been told that scanf() stops reading >input > > when it encounters a space, but that appears not to be so here. As I >said > > earlier, the scanf and gets functions only work every other time, I > > believe > > that is because when I hit the <return> key the <return> is >automatically > > entered as the input to the next input function. > > > > ??? > > > > _________________________________________________________________ > > Express yourself instantly with MSN Messenger! Download today - it's >FREE! > > http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ > > > > > > >------------------------------------------------------------------------- > > Take Surveys. Earn Cash. Influence the Future of IT > > Join SourceForge.net's Techsay panel and you'll get the chance to share > > your > > opinions on IT & business topics through brief surveys -- and earn cash > > >http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV > > _______________________________________________ > > MinGW-users mailing list > > Min...@li... > > > > You may change your MinGW Account Options or unsubscribe at: > > https://lists.sourceforge.net/lists/listinfo/mingw-users > > > > >------------------------------------------------------------------------- >Take Surveys. Earn Cash. Influence the Future of IT >Join SourceForge.net's Techsay panel and you'll get the chance to share >your >opinions on IT & business topics through brief surveys -- and earn cash >http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV >_______________________________________________ >MinGW-users mailing list >Min...@li... > >You may change your MinGW Account Options or unsubscribe at: >https://lists.sourceforge.net/lists/listinfo/mingw-users _________________________________________________________________ Dont just search. Find. Check out the new MSN Search! http://search.msn.click-url.com/go/onm00200636ave/direct/01/ |
From: Gianluca S. <gi...@gm...> - 2006-07-21 07:04:38
|
On 7/21/06, Felix VIII <alp...@ho...> wrote: > For some reason when I use "%1s" it only reads the fourth character input > (d): > [test.c] > #include <stdio.h> > > int main() > { > char a,b,c,d; > int e,f,g,h; > printf("start"); > e=fscanf(stdin,"%1s",&a); > f=fscanf(stdin,"%1s",&b); > g=fscanf(stdin,"%1s",&c); > h=fscanf(stdin,"%1s",&d); > printf("\n\n\"%c%c%c%c\"=character input\n",a,b,c,d); > printf("%d%d%d%d=fscanf output",e,f,g,h); > } > >From the "man printf" page: s Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null character ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first. so I think you are not giving enough room to store the requested 1 character string; try changing char a,b,c,d; in char a[2],b[2],c[2],d[2]; and you will see something different; if you want to see the correct string from printf, please do not forget to change the line printf("\n\n\"%c%c%c%c\"=character input\n",a,b,c,d); accordingly. Cheers Gianluca |
From: Keith M. <kei...@to...> - 2006-07-21 13:41:55
|
Gianluca Sforna wrote: > From the "man printf" page: > > s Matches a sequence of non-white-space characters; the next > pointer must be a pointer to character array that is long enough > to hold the input sequence and the terminating null character > ('\0'), which is added automatically. The input string stops at > white space or at the maximum field width, whichever occurs > first. Which, quoted in isolation, is potentially misleading, for it suggests that if the first char encountered is white space, then the input will be a null string; this is *not* the case. In fact, scanf first skips over any leading white space, *before* it starts to fetch the string input, and there is no defined mechanism whereby it can ever return a null (zero length) string. It *is* true that parsing stops at the first white-space byte, *after* detecting the first non-white-space character. This means that scanf can never parse a string *containing* white space, with a single `%s' conversion spec; this is completely inconsistent with the behaviour of `%s' in a `printf' format spec. $ cat scanf-test2.c #include <stdio.h> int main() { char c[512]; scanf( "%511s", c ); printf( "You entered '%s'\n", c ); return 0; } $ gcc -o scanf-test2.exe scanf-test2.c $ ./scanf-test2 this is a test You entered 'this' Incidentally, this little test case can be used to show the importance of verifying the return value from functions such as scanf, (which this *doesn't*. If I run it thus: $ ./scanf-test2 < nul You entered '<random-garbage-appears-here>' the unexpected result might lead me to suspect that scanf is broken, but this is not so, for the standard says: http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html | If end-of-file is encountered during input, conversion shall be | terminated. If end-of-file occurs before any bytes matching the | current conversion specification (except for %n ) have been read | (other than leading white-space characters, where permitted), | execution of the current conversion specification shall terminate | with an input failure. Otherwise, unless execution of the current | conversion specification is terminated with a matching failure, | execution of the following conversion specification (if any) shall | be terminated with an input failure. So, this apparent breakage is simply an example of an error, which *I* should have trapped, but didn't; I should be validating my input, to avoid such unfortunate surprises: $ cat scanf-test3.c #include <stdio.h> int main() { char c[512]; if( scanf( "%511s", c ) == 1 ) printf( "You entered '%s'\n", c ); else fprintf( stderr, "Input error: no data found\n" ); return 0; } $ gcc -o scanf-test3.exe scanf-test3.c $ ./scanf-test2 this is a test You entered 'this' $ ./scanf-test3 < nul Input error: no data found BTW, that same POSIX Standard reference, cited above, also says: | Input white-space characters (as specified by isspace()) shall be | skipped, unless the conversion specification includes a [, c, C, or | n conversion specifier. which answers the OP's question about why white-space was not being skipped, when he used a `%c' conversion spec. Regards, Keith. |
From: Felix V. <alp...@ho...> - 2006-07-21 15:26:03
|
>BTW, that same POSIX Standard reference, cited above, also says: >| Input white-space characters (as specified by isspace()) shall be >| skipped, unless the conversion specification includes a [, c, C, or >| n conversion specifier. > >which answers the OP's question about why white-space was not being >skipped, when he used a `%c' conversion spec. > >Regards, >Keith. > So which format specifier should I use? '%1s' or ' %c', or the example you used: >#include <stdio.h> > >int main() >{ > char c[512]; > if( scanf( "%511s", c ) == 1 ) > printf( "You entered '%s'\n", c ); > else > fprintf( stderr, "Input error: no data found\n" ); >return 0; >} _________________________________________________________________ Express yourself instantly with MSN Messenger! Download today - it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/ |
From: Keith M. <kei...@to...> - 2006-07-21 15:55:45
|
Felix VIII wrote: > So which format specifier should I use? Only *you* can answer that, for it depends on what you are trying to achieve. In the simple example you posted, where you want to skip white space, then fetch one character, I'd tend to favour: int c, status; if( (status = scanf( " %c", &c )) == 1 ) /* do something */; else /* handle the `no input' error */; You've been pointed to plenty of references, which should help you to decide; read them and make your own choice. If you need clarification on M$'s implementation, (which Mingw uses), then you should go here: http://msdn.microsoft.com/library/default.asp and search for whatever function you are unsure about. Regards, Keith. |
From: Felix V. <alp...@ho...> - 2006-07-21 16:33:59
|
>From: Keith MARSHALL <kei...@to...> >Reply-To: Keith MARSHALL <kei...@to...>,MinGW Users List ><min...@li...> >To: MinGW Users List <min...@li...> >Subject: Re: [Mingw-users] scanf, fscanf, gets, fgetc, and >mostly-every-other-input-function problem >Date: Fri, 21 Jul 2006 16:54:27 +0100 > >Felix VIII wrote: > > So which format specifier should I use? > >Only *you* can answer that, for it depends on what you are >trying to achieve. I was expecting that ;-) >In the simple example you posted, where >you want to skip white space, then fetch one character, I'd >tend to favour: > > int c, status; > if( (status = scanf( " %c", &c )) == 1 ) > /* do something */; > else > /* handle the `no input' error */; > >You've been pointed to plenty of references, which should help >you to decide; read them and make your own choice. If you need >clarification on M$'s implementation, (which Mingw uses), then >you should go here: >http://msdn.microsoft.com/library/default.asp > >and search for whatever function you are unsure about. > >Regards, >Keith. > It seems that " %c" seems to solve my problems, so thank you. Felix. _________________________________________________________________ Dont just search. Find. Check out the new MSN Search! http://search.msn.click-url.com/go/onm00200636ave/direct/01/ |
From: Keith M. <kei...@to...> - 2006-07-21 09:17:09
|
Jeremy Bettis wrote: > ... To read next non-white-space single-byte character, use %1s; > to read next non-white-space wide character, use %1ws. Actually, this probably isn't the best advice. The OP's code had (my comments appended): char c; /* one byte of storage */ scanf( "%c", &c ); /* fetch next byte from stdin */ Now, this will fetch the next available byte from stdin, and store it in `c'. If that next byte happens to be a space, then `c' will become a space. However, if you change that format string to `"%1s"', as you suggest, then scanf will try to fetch a *string* of one byte in length, but it will also append a NUL, to terminate the string, so: char c; /* only one byte of storage */ scanf( "%1s", &c ); /* this is a buffer overrun... * one byte is fetched into `c', then a * terminating NUL is appended, in the * following memory address, where it * DEFINITELY doesn't belong! */ If you want to fetch single character input, but ignore leading white space, then you could use: char c; /* one byte of storage */ scanf( " %c", &c ); /* fetch next character from stdin, * ignoring leading white space, (if any). * no buffer overrun, because at most one * byte is stored. */ (note the space in the format string, *before* the `%c' conversion spec; this causes scanf to skip *all* leading white space). Thus: $ cat scanf-test.c #include <stdio.h> int main() { char c; scanf( " %c", &c ); printf( "You entered a '%c'\n", c ); return 0; } $ gcc -o scanf-test scanf-test.c $ ./scanf-test zzzzzzz You entered a 'z' which seems to be what the OP wanted. Regards, Keith. |