Thread: sscanf and memory allocation

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    41

    sscanf and memory allocation

    Hello All,

    I have the following code:

    Code:
                            if(f_peri) {
                                    c = 0;
                                    k = 0;
                                    char *ptr_periodicidade = periodicidade;
                                    printf("f_peri: [%d]\n",f_peri);
                                    strcpy(field_second,"");
                                    printf("1->field_second: [%s]\n",field_second);
                                    printf("c: [%d]\n",c);
                                    while ( sscanf(ptr_periodicidade, "%50[^,]%*c%n", field_second, &k) == 1 )
                                    {
                                            printf("k: [%d]\n",k);
                                            printf("2->field_second: [%s]\n",field_second);
                                            ptr_periodicidade += k;
                                            switch (c) {
                                                    default:
                                                            strcpy(data[c_line].periodicidade,field_second);
                                                            printf("second[%d]: [%s]\n",c,field_second);
                                                            break;
                                            }
                                            strcpy(data[c_line].path,path);
                                            c++;
                                            c_line++;
                                            printf("c_line: [%d]\n",c_line);
                                    }
                                    strcpy(periodicidade,"");
                                    strcpy(path,"");
                            } else {
                                    c_line++;
                            }

    That generate's this:

    field[0]: [1,10,20,30,40,50]
    default->field[1]: [/tmp/echo2.sh]
    f_peri: [1]
    1->field_second: []
    c: [0]
    k: [2]
    2->field_second: [1]
    second[0]: [1]
    c_line: [1]
    k: [3]
    2->field_second: [10]
    second[1]: [10]
    c_line: [2]
    k: [3]
    2->field_second: [20]
    second[2]: [20]
    c_line: [3]
    k: [3]
    2->field_second: [30]
    second[3]: [30]
    c_line: [4]
    k: [3]
    2->field_second: [40]
    second[4]: [40]
    c_line: [5]
    k: [3]
    2->field_second: [50]
    second[5]: [50]
    c_line: [6]
    &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&



    field[0]: [25,55]
    default->field[1]: [/usr/bin/php]
    default->field[2]: [/html/echo4.php]
    f_peri: [1]
    1->field_second: []
    c: [0]
    k: [3]
    2->field_second: [25]
    second[0]: [25]
    c_line: [7]
    k: [3]
    2->field_second: [55]
    second[1]: [55]
    c_line: [8]
    k: [2]
    2->field_second: [0]
    second[2]: [0]
    c_line: [9]
    k: [3]
    2->field_second: [30]
    second[3]: [30]
    c_line: [10]
    k: [3]
    2->field_second: [40]
    second[4]: [40]
    c_line: [11]
    k: [3]
    2->field_second: [50]
    second[5]: [50]
    c_line: [12]
    &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&



    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    data[0].periodicidade: [1]
    data[0].path: [/tmp/echo2.sh ]
    data[1].periodicidade: [10]
    data[1].path: [/tmp/echo2.sh ]
    data[2].periodicidade: [20]
    data[2].path: [/tmp/echo2.sh ]
    data[3].periodicidade: [30]
    data[3].path: [/tmp/echo2.sh ]
    data[4].periodicidade: [40]
    data[4].path: [/tmp/echo2.sh ]
    data[5].periodicidade: [50]
    data[5].path: [/tmp/echo2.sh ]
    data[6].periodicidade: [25]
    data[6].path: [/usr/bin/php /html/echo4.php ]
    data[7].periodicidade: [55]
    data[7].path: [/usr/bin/php /html/echo4.php ]
    data[8].periodicidade: [0]
    data[8].path: [/usr/bin/php /html/echo4.php ]
    data[9].periodicidade: [30]
    data[9].path: [/usr/bin/php /html/echo4.php ]
    data[10].periodicidade: [40]
    data[10].path: [/usr/bin/php /html/echo4.php ]
    data[11].periodicidade: [50]
    data[11].path: [/usr/bin/php /html/echo4.php ]
    xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


    All that info is stored in the following struct:
    Code:
    struct MyData {
            char periodicidade[50];
            char path[400];
            int controle; 
    };

    The two lines beeing processed are:
    1,10,20,30,40,50 /tmp/echo2.sh
    25,55 /usr/bin/php /html/echo4.php


    As we can see in the output the first line is splited ok but the second line that has only two args (25 55) is completed with args 0, 30, 40 and 50 at the end. I think that last 3 numbers are on memory for pointer ptr_periodicidade.
    I've tryed to free the memory for that pointer with out sucess. Can any one help out ?

    Thanks alot,

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Some quick thoughts:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
       static const char filename[] = "file.txt";
       FILE *file = fopen(filename, "r");
       if ( file )
       {
          char line[256];
          while ( fgets(line, sizeof line, file) )
          {
             char *ptr = line;
             int value, n;
             while ( sscanf(ptr, "%d%*1c%n", &value, &n) == 1 )
             {
                printf("value = %d\n", value);
                ptr += n;
             }
             fputs(ptr, stdout);
          }
       }
       return 0;
    }
    
    /* my output
    value = 1
    value = 10
    value = 20
    value = 30
    value = 40
    value = 50
    /tmp/echo2.sh
    value = 25
    value = 55
    /usr/bin/php /html/echo4.php
    */
    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.*

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    41
    Hello Sinkula,

    Thanks for the tip !

    It now works inside the while, only the numbers on the file are printed. I think I've found the error... it was not at sscanf I think that is a problem with the struct. I've done:

    Code:
    if(f_peri) {
            char *ptr_periodicidade = periodicidade;
            char buffer[BUFSIZ];
            int value, q;
            while ( sscanf(ptr_periodicidade, "%d%*1c%n", &value, &q) == 1 )
             {
                    strcpy(buffer,"");
                    printf("=== [%s] ===\n",ptr_periodicidade);
                    printf("\tvalue = %d\n", value);
                    sprintf(buffer,"%d",value);
                    strcpy(data[c_line].periodicidade,buffer);
                    strcpy(data[c_line].path,path);
                    ptr_periodicidade += q;
                    c_line++;
             }
             //fputs(ptr, stdout);
    } else {
                    c_line++;
    }
    Here is the struct:

    Code:
    struct MyData {
            char periodicidade[50];
            char path[400];
            int controle;
    };
    Here is the struct printf:

    Code:
            for(x=0; x<c_line; x++) {
                    printf("data[%d].periodicidade: [%s]\n",x,data[x].periodicidade);
                    printf("data[%d].path: [%s]\n",x,data[x].path);
            }


    The output from the value printf was:
    === [25,55] ===
    value = 25
    === [55] ===
    value = 55
    === [0,30,40,50] ===
    value = 0
    === [30,40,50] ===
    value = 30
    === [40,50] ===
    value = 40
    === [50] ===
    value = 50


    This is correct !


    But the output from the struct was:
    data[0].periodicidade: [1]
    data[0].path: [/tmp/echo2.sh ]
    data[1].periodicidade: [10]
    data[1].path: [/tmp/echo2.sh ]
    data[2].periodicidade: [20]
    data[2].path: [/tmp/echo2.sh ]
    data[3].periodicidade: [30]
    data[3].path: [/tmp/echo2.sh ]
    data[4].periodicidade: [40]
    data[4].path: [/tmp/echo2.sh ]
    data[5].periodicidade: [50]
    data[5].path: [/tmp/echo2.sh ]
    data[6].periodicidade: [25]
    data[6].path: [/usr/bin/php /html/echo4.php ]
    data[7].periodicidade: [55]
    data[7].path: [/usr/bin/php /html/echo4.php ]
    data[8].periodicidade: [0]
    data[8].path: [/usr/bin/php /html/echo4.php ]
    data[9].periodicidade: [30]
    data[9].path: [/usr/bin/php /html/echo4.php ]
    data[10].periodicidade: [40]
    data[10].path: [/usr/bin/php /html/echo4.php ]
    data[11].periodicidade: [50]
    data[11].path: [/usr/bin/php /html/echo4.php ]



    The struct remains saving 0,30,40 and 50. I'm missing some thing ?

    Thanks again,

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    It would be helpful to see the declaration for data and some of the others to really understand the full context. I may be confused on some of the details, but here's my guesswork.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    struct MyData
    {
       char periodicidade[50];
       char path[400];
       int  controle;
    };
    
    int main(void)
    {
       static const char filename[] = "file.txt";
       FILE *file = fopen(filename, "r");
       if ( file != NULL )
       {
          char line[256];
          struct MyData data[100];
          size_t i = 0, j = i;
          while ( fgets(line, sizeof line, file) != NULL )
          {
             int n;
             char *ptr = strchr(line, '\n');
             if ( ptr != NULL )
             {
                *ptr = '\0';
             }
             ptr = line;
             while ( sscanf(ptr, "%d%*1c%n", &data[i].controle, &n) == 1 )
             {
                ptr += n;
                sprintf(data[i].periodicidade, "%d", data[i].controle);
                printf("data[%lu].controle = %d\n", (long unsigned)i,
                       data[i].controle);
                printf("data[%lu].periodicidade = \"%s\"\n", (long unsigned)i,
                       data[i].periodicidade);
                if ( ++i >= sizeof data / sizeof *data )
                {
                   puts("out of room");
                   goto done;
                }
             }
             for ( ; j < i; ++j )
             {
                strcpy(data[j].path, ptr);
                printf("data[%lu].controle = \"%s\"\n", (long unsigned)j,
                       data[j].path);
             }
          }
          done:
          puts("---Input Complete---");
          for ( j = i, i = 0; i < j; ++i )
          {
             printf("data[%lu] : { \"%s\", \"%s\", %d }\n", (long unsigned)i,
                    data[i].periodicidade, data[i].path, data[i].controle);
          }
       }
       return 0;
    }
    
    /* my output
    data[0].controle = 1
    data[0].periodicidade = "1"
    data[1].controle = 10
    data[1].periodicidade = "10"
    data[2].controle = 20
    data[2].periodicidade = "20"
    data[3].controle = 30
    data[3].periodicidade = "30"
    data[4].controle = 40
    data[4].periodicidade = "40"
    data[5].controle = 50
    data[5].periodicidade = "50"
    data[0].controle = "/tmp/echo2.sh"
    data[1].controle = "/tmp/echo2.sh"
    data[2].controle = "/tmp/echo2.sh"
    data[3].controle = "/tmp/echo2.sh"
    data[4].controle = "/tmp/echo2.sh"
    data[5].controle = "/tmp/echo2.sh"
    data[6].controle = 25
    data[6].periodicidade = "25"
    data[7].controle = 55
    data[7].periodicidade = "55"
    data[6].controle = "/usr/bin/php /html/echo4.php"
    data[7].controle = "/usr/bin/php /html/echo4.php"
    ---Input Complete---
    data[0] : { "1", "/tmp/echo2.sh", 1 }
    data[1] : { "10", "/tmp/echo2.sh", 10 }
    data[2] : { "20", "/tmp/echo2.sh", 20 }
    data[3] : { "30", "/tmp/echo2.sh", 30 }
    data[4] : { "40", "/tmp/echo2.sh", 40 }
    data[5] : { "50", "/tmp/echo2.sh", 50 }
    data[6] : { "25", "/usr/bin/php /html/echo4.php", 25 }
    data[7] : { "55", "/usr/bin/php /html/echo4.php", 55 }
    */
    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.*

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using SSCANF to get a variable
    By aladin in forum C Programming
    Replies: 3
    Last Post: 03-23-2009, 08:17 PM
  2. Malloc,calloc..Sscanf.
    By ozumsafa in forum C Programming
    Replies: 22
    Last Post: 07-26-2007, 01:09 AM
  3. Simple sscanf mystery
    By registering in forum C Programming
    Replies: 4
    Last Post: 06-10-2003, 11:47 PM