CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1

    Parse buffer

    Hi,

    I'm programming in C Ansi under Unix so a C (and not C++) answer would really be appreciated

    My program is supposed to get a text file from the net. This part is coded well (I think) and I get the file with 'GET file.txt HTTP/1.1'.

    Now I receive the file with a HTTP header like:

    HTTP/1.1 200 OK
    Date: Mon, 30 sep 2002 13:55:33 GMT
    [..]
    Content-Type: text/plain

    NAME=name1&SURNAME=surname1&ENTER=yes
    NAME=name2&SURNAME=surname2&ENTER=yes
    NAME=name3&SURNAME=surname3&ENTER=yes
    NAME=name4&SURNAME=surname4&ENTER=yes
    NAME=name5&SURNAME=surname5&ENTER=yes


    I wanted to parse the file to get NAME and SURNAME for each line with a 'while' loop and 'strstr' but it gets the first line and get it over and over..

    Please, what's the (best) way to parse a buffer and get all the NAME and SURNAME.

    I already have the part to manage the users so just help me with the loop part.

    Regards,

    Pierrick
    Last edited by tux0r; September 30th, 2002 at 09:36 AM.

  2. #2
    Join Date
    Dec 1999
    Location
    Québec, Qc, Canada
    Posts
    26
    It's not clear but I will suppose that you have the file in a char* buffer since your using strstr in your message. You're stick with the first line (I also suppose that you have skipped the header) because strstr works on a char* buffer (not on a stream). So if you call :

    Code:
    strstr( buffer, ... );
    strstr( buffer, ... );
    strstr( buffer, ... );
    etc.
    buffer points at the same memory location. You have to advance it yourself. But I rather use "sscanf" if I was you. I would do something like :

    Code:
    while( sscanf( buffer, "NAME=%s&SURNAME=%s&%s\n", nameBuffer, surnameBuffer, skipBuffer ) == 3 )
    {
        ...
    }
    The location of the buffer pointer is managed by sscanf. Also, be sure your temp. buffers have enough space. If the point of reading the file is just to extract what you do in the while-loop, use fscanf to read your file it will be fastest than reading the file then scaning the names. You'll read and scan in one step.

    Hope this help,
    Martin

  3. #3
    Join Date
    Feb 2002
    Posts
    5,757
    I am not sure if you can ignore certain data when you download data from a website via HTTP. If you want to filter data, you could use the /GET command and then save relevant data only.

    Kuphryn

  4. #4
    Thanx martin!

    The trouble is I still have the header in the buffer (since I assume the size is variable).

    And the sscanf is not working apparently.

    I try to do only one sscanf (so without the while loop).

    Like the following:

    char incodata[] = "NAME1=name1&SURNAME1=surname1&ENTER=1";
    int i = 0;
    i = sscanf (incodata, "NAME1=%s", info_name):
    printf ("\n%s\n", info_name);

    and it prints 0 !

    I don't know this function, so I read some stuff on the net and I cant figure out if I have to put the whole string like NAME1=%s&SURNAME1=%s&ENTER=%s"

    Anyway it's not working.

    Regards,

    Pierrick

  5. #5
    OK I tried to make it work the whole morning (switzerland time) and all I had is "segmentation fault" or infinite loop!

    I have a buffer which contains datas
    I didnt cut anything.. I have this buffer exactly as it is shown above.

    incodata is the buffer declared as char * with an malloc.

    What I am trying to do is to find every occurance of a word in this buffer.

    Something like


    while (get_the_next_line(incodata))
    if(strstr(incodata, "NAME1"))
    printf ("found\n"):


    So i tried the following:


    while(strstr(incdoata,"NAME1"))
    printf("found\n"):


    but it's looping for ever!

    Thanx for helping !

    Pierrick
    Last edited by tux0r; October 1st, 2002 at 06:03 AM.

  6. #6
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    READ what the other people have told you; to quote Martin:
    buffer points at the same memory location. You have to advance it yourself. But I rather use "sscanf" if I was you. I would do something like
    Why didn't you do as he suggested and use sscanf()?

    --Paul

  7. #7
    I tried with sscanf with no success.

    It always return 0!

    OK now I have the following:

    while( sscanf( incodata, "NAME=%s&SURNAME=%s&%s\n", info_login, info_passw, info_skipp ) == 3 )
    {
    printf ("found\n"):
    }

    it doesnt print 'found' !
    so it does not find what I'm looking for...

    Let me remember you that I have the HTTP header.. Do I have to take care about it ?

    thanx
    Last edited by tux0r; October 1st, 2002 at 06:59 AM.

  8. #8
    OK Full example of what I did.
    (Still not working).

    PHP Code:
    char incodata[]  = "NAME1=name1&SURNAME1=surname1&ENTER=Enter\nNAME1=name2&SURNAME1=surname2&ENTER=Enter";
      
    char *info_name = (char *) malloc (BUF_SZ);
      
    char *info_surname = (char *) malloc (BUF_SZ);
      
    char *info_skip = (char *) malloc (BUF_SZ);

    while( 
    sscanfincodata"NAME1=%s&SURNAME1=%s&%s"info_nameinfo_surnameinfo_skip ) == 3)
      {
         
    printf ("found\n");
      } 
    Is it enough to help ?

    Best Regards !

  9. #9
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    I looked at it and yeah you're right. The input buffer is not
    delimited by whitespace ... and that's how sscanf() delimits
    strings. You'll probably need to use strtok() and strstr() to find
    what you need. strtok() will go through the buffer for you. Don't
    nest strtok() calls because strtok() uses internal data to keep
    track of where it's at.

  10. #10
    - Don't nest strtok() calls because strtok() uses internal data to keep
    track of where it's at.

    donc nest ?

  11. #11
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    DON'T do the following:
    Code:
    char buffer[] ="blah\tblah\nblah\tblah\nblah\tblah\n";
    char* pToken = 0;
    char* pInnerToken = 0;
    
    // get by line
    pToken = strtok(buffer, "\n");
    while (pToken != 0)
    {
       // get by tab
       pInnerToken = strtok(pToken, "\t");
       while (pInnerToken != 0)
       {
          // this probably screwed something up.
          // don't nest strtok()'s 
          pInnerToken = strtok(0, "\t");
       }
       
       pToken = strtok(0, "\n");
    }
    You'd have to use a different method to parse the inner string.

    --Paul

  12. #12
    Thanx to all of you for the help !!

    I finally did it the following way:

    PHP Code:
      char my_str[] = "http header + carriage return + NAME1 and SURNAME1 bla bla .....";
      
    char *p;
      
    char *info_name = (char *) malloc (1024);
      
    char *info_surname = (char *) malloc (1024);
      
      
    strstr(my_str"NAME1");
      
    strtok(p"& \n");
      
      while ( 
    != NULL)
      {
         if (
    strstr(p"NAME1"))
         {
            
    strcpyinfo_namestrlen("NAME1") + 1);
            
    printf ("Name: %s\n"info_name);
         }
         else if (
    strstr(p"SURNAME1"))
         {
            
    strcpyinfo_surnamestrlen("SURNAME1") + 1);
            
    printf ("Surname: %s\n\n"info_surname);
         }

         
    strtok (NULL"& \n");
      } 
    I know it's really awful (like the strlen("NAME1")) but it was just a quick test

    I will modify it to use #define and stuff.

    I don't know if it's the best solution to do it but it's working and since I didn't find any examples on the net I had to do it myself


    Cya

  13. #13
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    Hello,

    I know you said that this is just an example and you'll probably
    fix this anyway ... but I have to point out that the use of malloc()
    requires the use of a free() unless you want to have a memory
    leak.

    Code:
    char* pBuffer = malloc(1024);
    free(pBuffer);
    With the example you're using, you might as well use local char
    arrays; you'll have the same fixed-size limitation, but you won't
    have to worry about the dynamic memory allocation routines
    like malloc() or free(). Here's your routine modified so that the
    dynamic memory allocation business has been removed:

    Code:
    char my_str[] = "http header + carriage return + NAME1 and SURNAME1 bla bla .....";
      char *p;
      char info_name[1024];
      char info_surname[1024];
      
      p = strstr(my_str, "NAME1");
      p = strtok(p, "& \n");
      
      while ( p != NULL)
      {
         if (strstr(p, "NAME1"))
         {
            strcpy( info_name, p + strlen("NAME1") + 1);
            printf ("Name: %s\n", info_name);
         }
         else if (strstr(p, "SURNAME1"))
         {
            strcpy( info_surname, p + strlen("SURNAME1") + 1);
            printf ("Surname: %s\n\n", info_surname);
         }
    
         p = strtok (NULL, "& \n");
      }
    If you don't make the change I recommend, you'll have to use a
    free() at the end of your code.

    --Paul

  14. #14
    What's better or more "pro", malloc/free or without memory business ?

    Thanx for your support.. I appreciate your advices !

  15. #15
    Join Date
    May 2000
    Location
    Phoenix, AZ [USA]
    Posts
    1,347
    The best rule of thumb to go by while programming is "Keep it as
    simple as possible". malloc() is useful when you don't know the
    size of the buffer in advance. Let's say you are creating a string
    and you're creating it from user-input. What if you use a 64 byte
    buffer and the user inputs 100 bytes? So you'd develop a routine
    that counts the number of bytes input by the user and then use
    malloc() to create a dynamic buffer, which would hold this
    information. In your example, you are not using any complex
    algorithm requiring a dynamically-growing character array. There-
    fore, I'd suggest you use the character array in this case.

    That's not to say that malloc() doesn't have its uses; it is slightly
    more difficult to use, however, so use it more judiciously.

    --Paul

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured