1

Possible Duplicate:
How do you allow spaces to be entered using scanf?
How can I scan strings with spaces in them using scanf()?

New to C and I feel this should be very simple but for some reason I'm not seeing the clear answer.

Trying to write a name and address to a file but if I put 'FirstName LastName' only FirstName gets entered into the file. Same with address. Is there a way to accept the whole name with the space into the file?

struct person{
     char name[20];
     char address[50];
     char telno[20];
} info;

fp=fopen("contacts","a")

printf("Enter Name : ");
scanf("%s",info.name);

printf("Enter Address : ");
scanf("%s",info.address);

fprintf(fp,"%20s %20s %20s",info.name,info.address,info.telno);
fclose(fp);

New to C so please excuse my ignorance. Thanks.

Community
  • 1
  • 1
  • Topic about using space with scanf -> http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf – Camille G. Dec 19 '12 at 16:16
  • 2
    Don't use plain `scanf("%s", ...)`. Use `scanf("%19s", ...)` or something like that instead. – netcoder Dec 19 '12 at 16:17

4 Answers4

4

The only way to read "white space" in to a string with scanf() is with the negated scanset:

// This will read into comment everything up until the newline
scanf(" %[^\n]",info.name); 

In general the answer you're going to get however is to "not use scanf" and use fgets() instead:

fgets(info.name, sizeof info.name, stdin);

Don't forget a lot of this info for scanf() and fgets() and others is easy to get with a quick search.


Edit: I tried replacing scanf with fgets but when I run the program it skips past the "Enter Name:"

If it's "skiping" by your fgets() that means that your fgets() just read a left over character that was sitting on the stdin buffer. I'd wager a guess it was a newline character.

When you enter a string:

john smith

You're getting a newline '\n' appended to the end after the 'h'. That means scanf() is going to read the letters and leave the newline, fgets() on the other hand will read everything up to/including the newline. So if you were to do this:

scanf("%s",info.name);

fgets(info.address, sizeof info.address, stdin);

The fgets() would appear to be "skipped". If you're saying replacing both with fgets() is skipping the first one, then your stdin buffer isn't clean and you must have something before hand leaving a newline character on it.

Mike
  • 47,263
  • 29
  • 113
  • 177
  • I tried replacing scanf with `fgets(info.name, sizeof info.name, stdin);` but when I run the program it skips past the "Enter Name:" part and goes straight to "Enter Address:" (_Enter Name : Enter Address :_) – fixafone123 Dec 19 '12 at 16:21
  • @fixafone123 - then you're not showing the whole code. Note: if you do this in a loop or a `scanf` or `getchar` prior to the `fgets` then you're going to just read a newline character (it will seem like it's skiping the "enter") – Mike Dec 19 '12 at 16:28
  • You can try and use fflush(stdin) to flush the buffer after you use scanf if you want to continue using scanf. – AdmiralJonB Dec 19 '12 at 16:33
  • @AdmiralJonB - No. `fflush(stdin)` is undefined behavior. It should not be done and should not be recommended to be done. – Mike Dec 19 '12 at 16:34
  • @Mike, that was it. I have a selection menu that was getting input via scanf so my fgets was reading the newline character from that. Thanks! – fixafone123 Dec 19 '12 at 16:36
  • @Mike I had no idea it was undefined behaviour. Thanks for pointing it out. – AdmiralJonB Dec 19 '12 at 16:42
  • @AdmiralJonB - NP. It's suggested all the time and is a bit of a pet peeve of mine. The man pages for `fflush()` says it works to clean the input buffer, but then they also say: `The standards do not specify the behavior for input streams`. So it typically works, but because it's not specified, it's technically UB. – Mike Dec 19 '12 at 16:46
3

scanf(3) stops converting arguments when it finds whitespace. Try fgets(3).

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
2

Is there a way to accept the whole name with the space

Yes, use fgets() (it's generally advisable to use this function instead of scanf(), because scanf() doesn't always do what you think it does anyway):

fgets(info.name, sizeof(info.name), stdin);
0

scanf("%[^\r\n]",info.name);

This means accept everything except CR and LF.