Author |
Message |
nycol #1 / 11
|
 Newbie Scanf Puzzles
Hi, I've been learning C for about two days now, and am a bit puzzled by a couple of things to do with scanf: Firstly, if I get a string from scanf, and the input contains a space, it seems to cut the rest of the input off when I try to display the string with printf. For example: Tell me your name John Doe Hello John The code I'm using is: #include <stdio.h> void main() { char name[20]; printf("Tell me your name\n"); scanf("%s",&name); printf("Hello %s\n",name); Quote: }
Secondly, and don't laugh at this: in "C For Dummies", several of the lessons and examples contain statements like this: scanf("%s",name); Which I understood to be a bit of a mistake, as it's telling scanf to send the input to a variable, rather than a pointer to a variable. Is that ever valid with scanf? Compiler doesn't seem to like it much. Am using lccwin on NT4. Only writing command line programs for now. TIA, N../
|
Sun, 26 Oct 2003 20:20:11 GMT |
|
 |
Bill Godfre #2 / 11
|
 Newbie Scanf Puzzles
Short version: Use fgets() with stdin as the file instead. Long version: Quote: > char name[20]; > scanf("%s",&name);
scanf with %s expects a pointer to char. You are passing in a pointer to array of char. Pointer to char may have a different representation to other pointers. Passing in name (without the &) is correct. Remember, giving the name of an array yields a pointer to the first memmber. As for your other problem, of the scanning stopping at spaces. Use fgets() instead. You get a whole line, or as far as the space you have allocated. Quote: > printf("Hello %s\n",name);
You should avoid this form, and the gets() function. Consider what would happen if you typed in 30 characters. scanf doesn't know that only 20 characters are available. I would tell you the correct format to pass into scanf to do what you want, but I don't know it, and fgets is better anyway. Bill, president of the fgets() advocy group. -- "Dave is taller than me." - Tree.
|
Sun, 26 Oct 2003 20:44:38 GMT |
|
 |
386s #3 / 11
|
 Newbie Scanf Puzzles
Quote:
> Hi,
Hi. Quote: > I've been learning C for about two days now, and am a bit puzzled by a > couple of things to do with scanf: > Firstly, if I get a string from scanf, and the input contains a space, > it seems to cut the rest of the input off when I try to display the > string with printf.
See these FAQs: http://www.eskimo.com/~scs/C-faq/q12.17.html http://www.eskimo.com/~scs/C-faq/q12.19.html http://www.eskimo.com/~scs/C-faq/q12.20.html Quote: > For example: > Tell me your name > John Doe > Hello John > The code I'm using is: > #include <stdio.h> > void main()
See these FAQs: http://www.eskimo.com/~scs/C-faq/q11.12.html http://www.eskimo.com/~scs/C-faq/q11.14.html http://www.eskimo.com/~scs/C-faq/q11.15.html Quote: > { > char name[20]; > printf("Tell me your name\n"); > scanf("%s",&name); > printf("Hello %s\n",name); > } > Secondly, and don't laugh at this: in "C For Dummies", several of the > lessons and examples contain statements like this: > scanf("%s",name);
See these FAQs: http://www.eskimo.com/~scs/C-faq/q6.3.html http://www.eskimo.com/~scs/C-faq/q6.4.html http://www.eskimo.com/~scs/C-faq/q6.8.html http://www.eskimo.com/~scs/C-faq/q6.9.html http://www.eskimo.com/~scs/C-faq/q6.12.html Quote: > Which I understood to be a bit of a mistake, as it's telling scanf to > send the input to a variable, rather than a pointer to a variable. Is > that ever valid with scanf? Compiler doesn't seem to like it much.
See this FAQ: http://www.eskimo.com/~scs/C-faq/top.html It has lots of frequently asked/answered questions. :) -- 386 See this FAQ: http://www.eskimo.com/~scs/C-faq/top.html
|
Sun, 26 Oct 2003 22:54:36 GMT |
|
 |
Richard Heathfiel #4 / 11
|
 Newbie Scanf Puzzles
Quote:
> Hi, > I've been learning C for about two days now, and am a bit puzzled by a > couple of things to do with scanf:
Oh dear... :-) scanf is a lot harder than it looks, isn't it? Quote: > Firstly, if I get a string from scanf, and the input contains a space, it > seems to cut the rest of the input off when I try to display the string with > printf.
No, it cuts it off before that. scanf("%s", arrayname); - as well as being a security problem because of buffer overruns - stops scanning for a string at the first space it encounters, since it assumes the space to be a field separator. Quote: > For example: > Tell me your name > John Doe > Hello John > The code I'm using is: > #include <stdio.h> > void main()
Whichever book you got this out of, please burn it (and post footage of the event on the Web). The main function returns int. It has always returned int, it returns int now, and there's no reason to expect it will ever return anything else but int. Change the line to: int main(void) Quote: > { > char name[20]; > printf("Tell me your name\n"); > scanf("%s",&name);
Error: name is an array of char, so its name (in a value context) points to the first element in the array. &name is of type char (*)[20], or "pointer to array of 20 char" which isn't what you want here. Quote: > printf("Hello %s\n",name);
Because main returns int, add this line: return 0; Quote: > } > Secondly, and don't laugh at this: in "C For Dummies", several of the > lessons and examples contain statements like this: > scanf("%s",name); > Which I understood to be a bit of a mistake,
Right. It's a very dangerous way to use scanf. Quote: > as it's telling scanf to send > the input to a variable, rather than a pointer to a variable.
No, that's not the mistake. The mistakes are (1) the way the book shows you to use scanf, which is potentially extremely dangerous and (2) the way (IMNSHO) the book tries to introduce you to such an advanced function before you even know the difference between a variable and an array. (Some clueful people here disagree with my opinion of scanf, by the way, and you should give some consideration to their views rather than just accepting blindly what I say about it.) http://users.powernet.co.uk/eton/clc/cbooks.html has a list of books which are generally considered non-sucking by most denizens of this newsgroup. "C For Dummies" is *not* on that list. --
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html K&R answers, C books, etc: http://users.powernet.co.uk/eton
|
Sun, 26 Oct 2003 23:09:09 GMT |
|
 |
Matt Gessne #5 / 11
|
 Newbie Scanf Puzzles
Quote:
> Hi, > I've been learning C for about two days now, and am a bit puzzled by a > couple of things to do with scanf: > Firstly, if I get a string from scanf, and the input contains a space, it > seems to cut the rest of the input off when I try to display the string with > printf. > For example: > Tell me your name > John Doe > Hello John > The code I'm using is: > #include <stdio.h> > void main() > { > char name[20]; > printf("Tell me your name\n"); > scanf("%s",&name); > printf("Hello %s\n",name); > }
You need to read the whole thing into a buffer with something like fgets and then parse the output. Quote: > Secondly, and don't laugh at this: in "C For Dummies", several of the > lessons and examples contain statements like this: > scanf("%s",name); > Which I understood to be a bit of a mistake, as it's telling scanf to send > the input to a variable, rather than a pointer to a variable. Is that ever > valid with scanf? Compiler doesn't seem to like it much.
The name of the array IS it's address... So saying name is the same as saying &name or &name[0] Quote: > Am using lccwin on NT4. Only writing command line programs for now. > TIA, > N../
|
Sun, 26 Oct 2003 23:22:11 GMT |
|
 |
386s #6 / 11
|
 Newbie Scanf Puzzles
Quote:
>> scanf("%s",name); >> Which I understood to be a bit of a mistake, as it's telling scanf to >> send the input to a variable, rather than a pointer to a variable. Is >> that ever valid with scanf? Compiler doesn't seem to like it much. >The name of the array IS it's address...
Address of its first element, in this context. Quote: > So saying > name > is the same as saying > &name
Nope. See this FAQ: http://www.eskimo.com/~scs/C-faq/q6.12.html Quote: > or > &name[0]
Yep. These articles might be of interest (among others):
-- 386 See this FAQ: http://www.eskimo.com/~scs/C-faq/top.html
|
Sun, 26 Oct 2003 23:52:31 GMT |
|
 |
nycol #7 / 11
|
 Newbie Scanf Puzzles
Quote:
> >> scanf("%s",name); > >> Which I understood to be a bit of a mistake, as it's telling scanf to > >> send the input to a variable, rather than a pointer to a variable. Is > >> that ever valid with scanf? Compiler doesn't seem to like it much. > >The name of the array IS it's address... > Address of its first element, in this context. > > So saying
snip Just wanted to say thanks to everyone for the help. I've had a look at some of the FAQs, and have been told by a friend never to use scanf - so I guess fgets() will do nicely as a replacement. Thanks again, N
|
Mon, 27 Oct 2003 00:11:01 GMT |
|
 |
386s #8 / 11
|
 Newbie Scanf Puzzles
Quote:
> Just wanted to say thanks to everyone for the help. I've had a look at > some of the FAQs, and have been told by a friend never to use scanf - > so I guess fgets() will do nicely as a replacement.
Beware of books with titles like "C For Dummies" or "C/C++ In About 20/30 Minutes Or So, Written In About 5/10 Minutes (Yawn, I Gotta Go To The Bank Now)". :) -- 386 See this FAQ: http://www.eskimo.com/~scs/C-faq/top.html
|
Mon, 27 Oct 2003 00:39:08 GMT |
|
 |
Paul D. Boy #9 / 11
|
 Newbie Scanf Puzzles
: I've been learning C for about two days now, and am a bit puzzled by a : couple of things to do with scanf: : Firstly, if I get a string from scanf, and the input contains a space, it : seems to cut the rest of the input off when I try to display the string with : printf. : For example: : Tell me your name : John Doe : Hello John Thats because scanf() uses whitespace as a field delimiter. It is best to not use scanf(). Many comp.lang.c posters recommend using a combination of fgets() and sscanf(). Check out the comp.lang.c FAQ especially question 12.20 and related questions. : The code I'm using is: : #include <stdio.h> : void main() main() is defined to return an 'int'. Proper declarations for main() are: 1) int main( void ) /* doesn't take command line arguments */ 2a) int main( int argc, char **argv ) /* takes command line arguments */ 2b) int main( int argc, char *argv[] ) /* equivalent to 2a above */ : Secondly, and don't laugh at this: in "C For Dummies", several of the : lessons and examples contain statements like this: Don't use "C for Dummies" (you are not a dummy, use a book which a) respects your intelligence, and b) provides accurate information). Regular posters to this group will be more than happy to provide you with titles of decent C programming books. Just ask. Paul -- Paul D. Boyle
North Carolina State University http://laue.chem.ncsu.edu/web/xray.welcome.html
|
Sun, 26 Oct 2003 20:44:25 GMT |
|
 |
Zoran Cutur #10 / 11
|
 Newbie Scanf Puzzles
Once upon a while "Bill Godfrey" Quote:
> Short version: Use fgets() with stdin as the file instead.
This remains the correct answer. Quote: > Long version: >> char name[20];
.... Quote: > I would tell you the correct format to pass into scanf to do > what you want, but I don't know it, and fgets is better anyway.
if( 1 != scanf("%19[^\n]", name)) { puts("Couldn't read your name, dying!"); exit(1); Quote: }
or even more puzzled: char format[80]; if( 0 > snprintf(format, sizeof format, "%%%d[^\n]", sizeof name - 1)) { puts("Can't construct Format-String for scanf call"); exit(1); Quote: }
if( 1 != scanf(format, name)) { puts("Couldn't read your name, dying!"); exit(1); Quote: }
That leads to the problem that there may be characters left in the input stream. So again the use of scanf in this purpose is not recommended. Quote: > Bill, president of the fgets() advocy group.
Zoran, your new member of the fgets() advocacy group. :-) Note: snprintf() is new in C99 and probably not available on your system/compiler. --
"LISP is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days." -- Eric S. Raymond
|
Mon, 27 Oct 2003 16:57:34 GMT |
|
 |
Matt Gessne #11 / 11
|
 Newbie Scanf Puzzles
Quote:
> >> scanf("%s",name); > >> Which I understood to be a bit of a mistake, as it's telling scanf to > >> send the input to a variable, rather than a pointer to a variable. Is > >> that ever valid with scanf? Compiler doesn't seem to like it much. > >The name of the array IS it's address... > Address of its first element, in this context. > > So saying > > name > > is the same as saying > > &name > Nope. > See this FAQ: > http://www.eskimo.com/~scs/C-faq/q6.12.html
I stand corrected. Apologies for the mistake.
|
Mon, 27 Oct 2003 21:58:59 GMT |
|
|
|