Thread: scanf - strtok and space as delimiter?

  1. #1
    Registered User Bill Cosby's Avatar
    Join Date
    Sep 2004
    Posts
    11

    Question scanf - strtok and space as delimiter?

    Hello everyone,

    I want to read a string with scanf and then devide it into two parts with strtok by using space as the delimiter.

    Well, till now I'm this far

    Code:
    char str[MAX_CHARS];
    char *cmd;
    char *param;
    char delim[] = " ";
    	
    scanf("%s", str);
    
    cmd = strtok(str, delim);
    param = strtok(NULL, delim);
    This simply doesn't work with space, but if I use e.g. comma instead of space, everything works perfectly.
    I presume I have to alter the scanf call in some way, but I don't know how, and for the record if I use gets instead of scanf it works perfectly, too.

    Thanks in advance.

  2. #2
    Watch for flying houses. Nessarose's Avatar
    Join Date
    Sep 2004
    Posts
    46
    Try this:

    Code:
    scanf("%[a-z 0-9 ' '], str);
    This basically says to keep reading while it sees characters, digits, and white space.

  3. #3
    Registered User Bill Cosby's Avatar
    Join Date
    Sep 2004
    Posts
    11
    Thank you very much, it now works the same way as if I did
    Code:
    scanf("%s %s", str1, str2);
    but then I must enter space to get any results.
    Are there any possibilities to make it optional whether I want to enter one command or two?

    thanks again for your help
    Bill

  4. #4
    Watch for flying houses. Nessarose's Avatar
    Join Date
    Sep 2004
    Posts
    46
    I'm not sure if you can do it within scanf. To be honest when it comes to user input, I stick with fgets. But if you want to do it with scanf, then I would do something like this:

    Code:
    scanf("%[a-z 0-9 ' '], str);
    if (strchr(str, ' ') == NULL)
        printf("One argument.");
    else
        printf("Two arguments.");

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Bill Cosby
    I want to read a string with scanf
    Why scanf? Why not fgets?
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
       char line[80];
       fputs("prompt> ", stdout);
       fflush(stdout);
       if ( fgets(line, sizeof line, stdin) )
       {
          static const char delimiters[] = " \n";
          int items = 0;
          char *ptr = strtok(line, delimiters);
          while ( ptr )
          {
             ++items;
             printf("ptr = \"%s\"\n", ptr);
             ptr = strtok(NULL, delimiters);
          }
          printf("items = %d\n", items);
       }
       return 0;
    }
    
    /* my output
    prompt> one
    ptr = "one"
    items = 1
    
    prompt> one two
    ptr = "one"
    ptr = "two"
    items = 2
    
    prompt> one two three
    ptr = "one"
    ptr = "two"
    ptr = "three"
    items = 3
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User Bill Cosby's Avatar
    Join Date
    Sep 2004
    Posts
    11
    Thanks to both of you, I try fgets, but my problems were because of this
    Code:
    char delim[] = " ";
    I changed it to
    Code:
    char delim[] = " \n";
    like in your example, and now everything works fine

    many thanks guys.
    Last edited by Bill Cosby; 09-20-2004 at 10:39 AM.

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Quote Originally Posted by Nessarose
    Try this:

    Code:
    scanf("%[a-z 0-9 ' '], str);
    This basically says to keep reading while it sees characters, digits, and white space.
    Not necessarily. The C standard doesn't guarantee that a-z or 0-9 will be a range. Also, ' ' doesn't mean the same thing in a scanset as it does elsewhere. What you're really telling scanf (as per the standard) is to search for the characters 'a', '-', 'z', ' ', '0', '9', and '\''. By coincidence this will work given the right input, but it will also work for the wrong input as well depending on what it is.

    Oh, you also forgot to close your format string and you risk a buffer overflow.

    The correct way to do what you want given an array of size 100 is:
    Code:
    scanf ( "%100[ 0123456789abcdefghijklmnopqrstuvwxyz]", str );
    But even then you're missing out on upper case letters and there might also be a consideration of locale to specify valid letters.

    >scanf("%s", str);
    This won't work if you want a string with spaces. The reason is because %s stops at whitespace. You can force scanf to read strings with spaces, but it's ugly and obscure and unsafe and fgets is much better.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. 20q game problems
    By Nexus-ZERO in forum C Programming
    Replies: 24
    Last Post: 12-17-2008, 05:48 PM
  2. strtok with "" as delimiter?
    By fanoliv in forum C Programming
    Replies: 15
    Last Post: 06-19-2006, 12:44 PM
  3. strtok tokenizing on spaces as well as my delimiter
    By snowblind37 in forum C++ Programming
    Replies: 2
    Last Post: 06-15-2004, 12:39 AM
  4. Trouble with strtok()
    By BianConiglio in forum C Programming
    Replies: 2
    Last Post: 05-08-2004, 06:56 PM
  5. strtok for 'space'
    By BEEP BEEP in forum C Programming
    Replies: 2
    Last Post: 04-26-2003, 06:21 PM