Like Tree1Likes

Parsing string

This is a discussion on Parsing string within the C Programming forums, part of the General Programming Boards category; Hi All! I need to split string for command and its value. If i have "imax 1000" i need to ...

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    29

    Parsing string

    Hi All!
    I need to split string for command and its value.
    If i have "imax 1000" i need to get com = "imax", val = "1000".
    Code:
    void parse_command(char *str)
    {
         char *chr;
         bool is_val = false;
         char *com;
         char *val;
         
         chr = str;
         
         while(*chr)
         {
            if(*chr != '\n' && *chr != '\0' && *chr != 32 /*space*/)
            {
                 if(!is_arg)
                 {
                     strcat(com, chr);
                 }
                 else
                 {
                     strcat(val, chr);
                 }
               
            }
            if(*chr == 32)
            {
                is_arg = true;    
            }
            chr++;
         }
             printf("%s",com); 
             printf("%s",val); 
    }
    It compiles ok but in run time programm stops responding.
    P.S. It can be more then one spase between two strings.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,558
    > strcat(com, chr);
    > strcat(val, chr);
    And where are these pointing?
    You have two garbage pointers, so just let loose the hell-hounds.
    Lesshardtofind likes this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    29
    I've changed it:
    strcat(com, *chr);
    strcat(val, *chr);
    Now i get :"\main.c [Warning] passing arg 2 of `strcat' makes pointer from integer without a cast "

  4. #4
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,558
    How about actually creating some memory you can store strings in?

    You know, like an array?
    Code:
    char foo[100] = { 0 };
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    29
    i did so :
    Code:
    char com[20] = {0};
    char val[20] = {0};
    The same result.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    See if this gives you any ideas.

    Code:
    #include <stdio.h>
    
    int main(void) {
       int i, val=0;
       char cmd[50]={0};
       char str[50]={"imax         1000"};
    
       sscanf(str,"%s %d",cmd,&val);
       printf("command: %s   value: %d \n",cmd,val);
    
       return 0;
    }

  7. #7
    Registered User
    Join Date
    May 2011
    Posts
    29
    Unfortunately sscanf is a resource-consuming function, considering the code should run on an atmel chip.
    Last edited by john7; 12-13-2012 at 08:10 AM.

  8. #8
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    It's going to concatenate the strings every loop, not just when you want it to. I'm guessing that's causing buffer overrun which is overriding your str pointer and causing your program to crash.
    Use *chr != ' ' instead. It's clearer and comments itself.
    You can remove the *chr != '\0' as it's a case that can never happen so is redundant. Or keep it for clarity whatever.
    bool is_arg is undefined.

  9. #9
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,558
    > if(*chr != '\n' && *chr != '\0' && *chr != 32 /*space*/)
    How many times is this going to be true, resulting in a strcat of a whole string to another string?

    > Unfortunately sscanf is a resource-consuming function, considering the code should run on an atmel chip.
    Have you run the code on your host machine?
    Have you run the code in a debugger to watch what happens?

    With a bit of careful prep, you can get 99% of the code to be run on the atmel to run on your host machine, at least to the point where you have a reasonable degree of confidence that it works.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  10. #10
    Registered User
    Join Date
    May 2011
    Posts
    29
    Thanks a lot guys for the help.
    Did some changes according your suggestion - still no success.
    I was trying to work with sscanf on atmel chip - it kills the chip, a lot of stuff going there.

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    2,381
    Will all of your commands be in the same format? If so, then maybe you can hard code a solution.

    Code:
    while current element is a letter character
        store that character in new array 1
    append a null character to new array 1
    
    while current element is a number character
        store that character in new array 2
    append a null character to new array 2
    This assumes you want the number portion as a string, not an integer, as implied in your first post.

  12. #12
    Registered User
    Join Date
    May 2011
    Posts
    29
    it'll be command and argument separated by one or more spaces, i think it' a quite trivial task to split the string, can't make up my mind how....yet

  13. #13
    Registered User
    Join Date
    Nov 2012
    Posts
    1,109
    Have you tried strtok? Does this also "kill" your chip? You could also write your own tokenizer which performs this task; the job is tedious but not difficult. The approach used by strtok is to scan through the string character by character. If the current character matches one of the delimiters, replace it by a '\0'. The result is that you have a tokenized set of null-terminated strings.

  14. #14
    Registered User
    Join Date
    May 2011
    Posts
    29
    Did it a bit clumsy way but it works.
    Code:
    void parse_command(char *str)
    {
         char *chr;
         bool is_arg = false;
         char com[20] = {0};
         char val[20] = {0};
         int idx = 0;
         
         chr = str;
         
         while(*chr)
         {
            if(*chr != 32 /*space*/)
            {
               if(!is_arg)
               {
                  com[idx++] = *chr;
               }
               else
               {
                   val[idx++] = *chr;
               }
               
            }
            if(*chr == 32)
            {
                is_arg = true;
                idx = 0;    
            }
            chr++;
         }
    
         com[strlen(com) + 1] = '\0';
         val[strlen(val) + 1] = '\0';
    
         printf("%s\n",com); 
         printf("%s\n",val);
    }

  15. #15
    Registered User
    Join Date
    Nov 2012
    Posts
    1,109
    Solving the problem is what counts. Being "elegant" or something can be a second goal most of the time.

    What is the purpose of these lines:

    Code:
    com[strlen(com) + 1] = '\0';
         val[strlen(val) + 1] = '\0';
    If you can run strlen on the arguments, then there already is a '\0' there. Do you need to ensure there are two '\0's at the end of the string?

    Why not pass in the com and val buffers as arguments to the function? Then you can call it easily from an outer function:

    Code:
    read_special_command(cmd);
    parse_command(cmd, arg1, arg2);
    Also its up to you but I like to name it the other way, command_read, command_parse, etc. Then all the "command_" stuff sorts nicely together


    EDIT: You can replace

    Code:
    chr = str;
    
    while (*str)
    {
    ...
       chr++;
    }
    with

    Code:
    for (chr = str; *str; chr++)
    That's what a for loop is for
    Last edited by c99tutorial; 12-13-2012 at 12:25 PM.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String Parsing
    By Shaun32887 in forum C++ Programming
    Replies: 11
    Last Post: 07-02-2008, 02:15 PM
  2. parsing a string
    By Coding in forum C++ Programming
    Replies: 10
    Last Post: 02-24-2008, 05:01 AM
  3. String parsing(parsing comments out of HTML file)
    By slcjoey in forum C# Programming
    Replies: 0
    Last Post: 07-29-2006, 08:28 PM
  4. string parsing
    By misplaced in forum C++ Programming
    Replies: 6
    Last Post: 09-30-2004, 11:50 PM
  5. String parsing
    By Cbuild in forum C Programming
    Replies: 5
    Last Post: 05-03-2004, 05:15 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21