Thread: Parsing a line and saving args

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    10

    Parsing a line and saving args

    I am writing a program in which I must read in a line of text which contain a command and its arguments. I have to parse the the line and break it up into its individual componets so that I can compare each command with what to do. I.E. if "bye" is typed the program must exit. I pretty much know how to parse the line but I do not know how I can then save each componet for comparison. Here is the code I have so far to prompt, read in, and parse the line:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    
    main()
    {
      char *cptr, *csh;
      char buffer[256];
    
      printf("sh%% ");
      cptr = fgets(buffer, 256, stdin);
    
      csh = strtok(buffer, " ");
      while(csh != NULL)
        {
          /*What can I put here to save each individual word?
          for comparison?*/
    
          csh = strtok(NULL, " ");
        }
    }
    Thanks a lot

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    How about adding something like:
    Code:
    char **args = NULL;
    int nargs = 0;
    
    ...inside the while() loop...
    args = realloc(args, sizeof(char *)*(nargs+1));
    args[nargs] = malloc(strlen(csh)+1);
    strcpy(args[nargs], csh);
    nargs++;
    With the proper error checking of course
    If you understand what you're doing, you're not learning anything.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    well, you don't *have* to store the individual tokens - you could simply write your command-processing function as it is, parsing each token as needed. otherwise, you could, for instance, create a two-dimensional array of chars to store each 'command' (making sure to keep track of the number of elements in use):

    Code:
    const int MAX_LINES = 1024, MAX_BUFF = 256;
    char array[MAX_LINES][MAX_BUFF+1];
    int i, size = 0;
    csh = strtok(buffer, " ");
    while(csh != NULL && size < MAX_LINES)
        {
          strncpy(array[size++], buffer, MAX_BUFF);
          csh = strtok(NULL, " ");
        }
    for(i = 0; i < size; ++i) 
        {
          printf("array[%d] = '%s'.\n", i, array[i]);
        }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User
    Join Date
    Sep 2004
    Posts
    10
    Thanks for the quick replies guys. So far i've only tried itsme86's code but I am getting a couple of errors:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    main()
    {
      char *cptr, *csh;
      char buffer[256];
      char **args = NULL;
      int nargs = 0;
    
      printf("sh%% ");
      cptr = fgets(buffer, 256, stdin);
    
      csh = strtok(buffer, " ");
      while(csh != NULL)
        {
          args = realloc(args, sizeof(char *)*(nargs + 1));
          args[nargs] = malloc(strlen(csh) + 1);
          strcpy(args[nargs], csh);
          nargs++;
    
          csh = strtok(NULL, " ");
        }
    }

    Code:
    project1a.c: In function `int main()':
    project1a.c:25: invalid conversion from `void*' to `char**'
    project1a.c:26: invalid conversion from `void*' to `char*'
    If somebody could do me a favore and explain to me what
    Code:
    char **args = NULL;
    does, specifically the double **, I don't seem to recall learning that.

    Thanks

  5. #5
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    If somebody could do me a favore and explain to me what
    Code:

    char **args = NULL;


    does, specifically the double **, I don't seem to recall learning that.

    Thanks
    its just another way of writing
    Code:
    char *args[]=NULL;
    its a pointer to pointer of chars. or in the above code x arrays of ptr to chars. personal preference.
    Last edited by caroundw5h; 09-08-2004 at 10:07 PM.
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Unless I forgot how to count, the line numbers from the errors you posted don't match up with the source code you posted. I'm guessing the errors correspond to the realloc() and malloc() lines.

    Which compiler are you using? You should only have to cast the return value of realloc() and malloc() with C++ (g++), not C (gcc).

    The only message I get when I compile the code you posted with gcc is that main() doesn't return a value.
    If you understand what you're doing, you're not learning anything.

  7. #7
    Registered User
    Join Date
    Sep 2004
    Posts
    10
    Ah I see, sorry I was doing g++, now there are no errors with gcc.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by itsme86
    Unless I forgot how to count, the line numbers from the errors you posted don't match up with the source code you posted. I'm guessing the errors correspond to the realloc() and malloc() lines.

    Which compiler are you using? You should only have to cast the return value of realloc() and malloc() with C++ (g++), not C (gcc).

    The only message I get when I compile the code you posted with gcc is that main() doesn't return a value.
    There are no errors in the code they've posted. Not so far as gcc is concerned. However, you will get a warning, compiling with -Wall:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    main()
    {
              char *cptr, *csh;
              char buffer[256];
              char **args = NULL;
              int nargs = 0;
              printf("sh%% ");
              cptr = fgets(buffer, 256, stdin);
              csh = strtok(buffer, " ");
              while(csh != NULL)
              {
                      args = realloc(args, sizeof(char *)*(nargs + 1));
                      args[nargs] = malloc(strlen(csh) + 1);
                      strcpy(args[nargs], csh);
                      nargs++;
                      csh = strtok(NULL, " ");
              }
    }
    imain.c:6: warning: return type defaults to `int' imain.c: In function `main': imain.c:22: warning: control reaches end of non-void function
    But that's to be expected, since it's obviously incorrect.

    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by pooty tang
    Ah I see, sorry I was doing g++, now there are no errors with gcc.
    Glad you figured it out.

    Quote Originally Posted by quzah
    There are no errors in the code they've posted. Not so far as gcc is concerned. However, you will get a warning, compiling with -Wall:
    That's what I said...
    If you understand what you're doing, you're not learning anything.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That's what I said...
    Sure, but you didn't expect them to get it the first time they're told did you? I guess you've never read any of C+++C_Forever's posts...

    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Sep 2004
    Posts
    10
    Ok, so now the command and its arguments are stored in args[]. Now I want it to keep prompting for new commands and its arguments until the user types "bye", im trying to do a string comparison with strcmp(args[0], "bye") but it does not seem to be working(never recognizes that they are equal). I know im doing it wrong but im unsure on how to go on about this part. Sorry if I am asking total noob questions but this is my first program using C. So if I could just be pointed on how to compare the string stored in the array with a user typed entry like "bye".

    Thanks a lot again, you guys have been a real help.

  12. #12
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Just use strcmp() with csh at the beginning the loop instead of using args[0]. That way their "bye" command doesn't get stored as a parameter.

    By the way, args[0] will always be the first word they typed in, not the last.
    If you understand what you're doing, you're not learning anything.

  13. #13
    Registered User
    Join Date
    Sep 2004
    Posts
    10
    Ok I used the strcmp(csh, "bye") on the outer while loop but it does not exit the while loop when I type bye. It isn't recognizing that they are equal.

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    main()
    {
      char *cptr, *csh;
      char buffer[256], bye[4] = "bye";
      char **args = NULL;
      int nargs = 0;
    
    
      printf("sh%% ");
      cptr = fgets(buffer, 256, stdin);
      csh = strtok(buffer, " ");
    
      while(strcmp(csh, "bye") != 0)
        {
          while(csh != NULL)
            {
              args = realloc(args, sizeof(char *)*(nargs + 1));
              args[nargs] = malloc(strlen(csh) + 1);
              strcpy(args[nargs], csh);
              nargs++;
    
              csh = strtok(NULL, " ");
            }
    
          nargs = 0;
          printf("sh%% ");
          cptr = fgets(buffer, 256, stdin);
          csh = strtok(buffer, " ");
        }
    }
    I tried using strcmp(csh, "bye") and strcmp(csh, bye) with bye being predefined and either way it always returns that they are unequal.

  14. #14
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by pooty tang
    Ok I used the strcmp(csh, "bye") on the outer while loop but it does not exit the while loop when I type bye. It isn't recognizing that they are equal.
    Leftover newline?
    FAQ > How do I... (Level 1) > Get a line of text from the user/keyboard (C)
    FAQ > How do I... (Level 1) > Comparing strings (C)
    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.*

  15. #15
    Registered User Frobozz's Avatar
    Join Date
    Dec 2002
    Posts
    546
    Try this:

    Code:
    while(strcmp(csh, "bye\n") != 0)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linked List Not Saving Value as Int
    By bar338 in forum C Programming
    Replies: 4
    Last Post: 05-04-2009, 07:53 PM
  2. Replies: 5
    Last Post: 03-02-2009, 08:33 AM
  3. Question about parsing a string from a line
    By edd1986 in forum C Programming
    Replies: 2
    Last Post: 04-23-2005, 03:18 PM
  4. Reading lines from a file and saving to a variable
    By Rare177 in forum C Programming
    Replies: 1
    Last Post: 06-09-2004, 03:47 PM
  5. Reading a line from a text file Please help
    By Blizzarddog in forum C++ Programming
    Replies: 7
    Last Post: 05-22-2003, 12:35 PM