8

I wanted to take character array from console and it also include white spaces, the only method i know in C is scanf, but it miss stop taking input once it hit with white space. What i should do?

Here is what i am doing.

char address[100];

scanf("%s", address);
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
itsaboutcode
  • 24,525
  • 45
  • 110
  • 156

7 Answers7

14

Try using fgets(). It will read a complete line from a stream of your choice (stdin, I guess you're looking for). An example for your case:

char address[100];

fgets(address, 100, stdin);

fgets() will read at most the number of characters passed in the second argument (minus one). No buffer overflow, and you'll get the whole line up to and including a newline character (or up to EOF). Note that since a maximum number of characters to read is one of the parameters, it is possible that you will get a partial line. Check to see if the last character in the returned string is '\n', and you'll know you got a complete line. EOF detection is pretty straightforward too; a NULL return value and a check to errno should help you out.

Thanks to Chris (below), for the point about partial lines.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • fgets look to have 3 parameters, 1. charter pointer. 2. int 3. File * What i should enter in second and third parameter? – itsaboutcode Oct 12 '09 at 17:04
  • 1
    +1 but note that the line may be longer than the character limit, so you should always check that the line you read ends in a `'\n'` character. – Chris Lutz Oct 12 '09 at 17:04
  • Thanks but i am in little trouble when i am using it, basically i am taking character input before that, which is scanf("%s", name); and then putting your line fgets(address, 100, stdin); it take the first input, which is name and program ends, so it is not coming to second line. But if i just ask for address, it works. How i can make sure it work for second line which is fgets(address, 100, stdin); – itsaboutcode Oct 12 '09 at 17:13
  • I don't think I understand your comment; why is the program ending? Can you show us some more of the code? – Carl Norum Oct 12 '09 at 17:15
  • yah sure, here is code. char name[20]; char address[100]; scanf("%s", &name); fgets(address, 100, stdin); – itsaboutcode Oct 12 '09 at 17:17
  • 2
    While we're on this subject (and this is related), due to the weird way in which `scanf()` handles whitespace, it is advised not to mix calls to `fscanf()` and calls to `fgets()` (or other reading utilities) on the same filehandle. The most commonly recommended pattern is to read the code into a string with `fgets()` and then use `sscanf()` on that string. That way, we have the best of both worlds, and we have them safely. – Chris Lutz Oct 12 '09 at 17:20
  • Oh, it's because your scanf() isn't reading the newline after the name is entered. So scanf() returns, and fgets() immediately reads a newline. Use fgets() for both calls, and I think you'll be set. – Carl Norum Oct 12 '09 at 17:21
  • @Chris I have to take Name first, which has no white spaces and then Address, which has white spaces.. So i am left with these options, which are not working for me. – itsaboutcode Oct 12 '09 at 17:22
  • I just hacked a little bit, i put getch() after scanf and then use fgets. It's working now. – itsaboutcode Oct 12 '09 at 17:32
  • @itsaboutcode, Chris has a good suggestion for you, to use fgets() to read whole lines and then get the pieces out using sscanf() afterwards. If you really have your heart set on using scanf() (which I don't recommend), just add a dummy read between reading the name and the address to eat the extra newline. – Carl Norum Oct 12 '09 at 17:34
  • @Charl Thanks man and this is what i have done. Just put a getch() in between them and it is working great. – itsaboutcode Oct 12 '09 at 17:38
  • @itsaboutcode, better use `getc(stdin);` because `getch()` isn't part of the ANSI C standard. – Nick Dandoulakis Oct 12 '09 at 17:43
  • @Nick D - Why not just `getchar();` ? – Chris Lutz Oct 13 '09 at 01:02
7

You can try something like this:

char str[100];
scanf("%99[0-9a-zA-Z ]s", str);
printf("%s\n", str);
Nick Dandoulakis
  • 42,588
  • 16
  • 104
  • 136
  • It is correct, but dont know why it is not working when i do this. char name[20]; char address[100]; scanf("%s", &name); fgets(address, 100, stdin); – itsaboutcode Oct 12 '09 at 17:19
1

There are ways to do it with scanf(), but in my humble opinion they get ugly fast. The common pattern (that surprisingly hasn't been mentioned yet) is to read the string in with fgets() and then use sscanf() to process it. sscanf() works like scanf(), only instead of processing the standard input stream, it processes a string that you pass to it (the same way printf() and sprintf() are related). The basics:

char s[100], str[100];
int i, x;
fgets(s, 100, stdin);
if(sscanf(s, "%d %x %s", &i, &x, str) != 3)
  {
    // our three variables weren't all set - probably an invalid string
    // either handle the error or set default values here.
  }
Community
  • 1
  • 1
Chris Lutz
  • 73,191
  • 16
  • 130
  • 183
0

See fgets()

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer.

char *fgets(char *s, int size, FILE *stream);

Further detail available in many SO questions, for example input-string-through-scanf.

(Due to popular demand, refrence to gets() was removed)

Community
  • 1
  • 1
gimel
  • 83,368
  • 10
  • 76
  • 104
  • 2
    From the page you linked: "Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead." – Fred Larson Oct 12 '09 at 17:15
  • It's nice to know that `gets()` exists, but it should never ever _ever_ be used (outside of code golf), and the OP seems a little new, so I seriously recommend just not mentioning that it exists. – Chris Lutz Oct 12 '09 at 17:22
  • Agree. gets() reference withdrawn. – gimel Oct 12 '09 at 18:00
0

Personally I would use fgets, but that has been already pointed out here. One way of doiung it using scanf would be

scanf("%[^\n]", address);

This takes in all chars until a '\n' is found.

MAK
  • 26,140
  • 11
  • 55
  • 86
0

If you want to take input until new line using a dynamic array inside struct, this may be useful:

#include<stdio.h>
#include<stdlib.h>

struct student{
char *name;
};

int main()
{
        struct student s;

        s.name = malloc(sizeof(char *));

        printf("Name: ");
        // fgets(s.name, 10, stdin); // this would limit your input to 10 characters.

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

        printf("You Entered: \n\n");

        printf("%s\n", s.name);
}
Nitaai
  • 2,577
  • 2
  • 15
  • 19
0

My style.

 #include <stdio.h>

    #define charIsimUzunlugu 30

        struct personelTanim
        {       
            char adSoyad[charIsimUzunlugu];             
        } personel;

    printf(" your char       : ");
    scanf("%[^\n]",personel.adSoyad);

    printf("\n\n%s",personel.adSoyad);
may
  • 1