strtok problem

Discussion in 'C Programming' started by Ram Laxman, Apr 11, 2004.

  1. Ram Laxman

    Ram Laxman Guest

    Hi all,
    I have written the following code:


    /* strtok example */
    #include <stdio.h>
    #include <string.h>

    static const char * const resultFileName = "param.txt";

    int main ()
    {

    FILE *fPtr;
    char str[300];
    char * pch;
    int len;
    char savedstr[300];

    fPtr =fopen(resultFileName, "r");

    if(fPtr == NULL)
    {
    printf("File doesnot exist");
    return 1;
    }

    else
    {
    while(!feof(fPtr))
    {
    fgets(str,288,fPtr);
    len = strlen(str);
    str[len-1]=0;
    for ( (pch=strtok(str,","));(pch = strtok(NULL,","));(pch
    !=NULL))
    {
    strncpy(savedstr,pch,len);
    printf("Saved String =%s\n",savedstr);
    }


    }

    }

    fclose(fPtr);
    return 0;

    }

    I have a text file as the following:
    param.txt:

    "ram","lax","deepak"
    10,20,30
    40,80,100
    70,90,100
    and so on...

    When I use strtok(delim ,) the problem is that the string "ram" never
    gets stored in savedstr array while from "lax" onwards it gets stored.

    1.Could any body suggest a better method so that I can store "ram"
    also in the saved string and tokenize based on comma separated
    delimiter?

    2.Is there anything in C like (map in C++) so that I can store:

    (key)
    "ram"---->10,40,70(In an array of integer values)
    "lax"---->20,80,90

    Could anybody help me in this regard?

    Regards
    Ram Laxman
     
    Ram Laxman, Apr 11, 2004
    #1
    1. Advertising

  2. Ram Laxman

    Sam Dennis Guest

    Ram Laxman wrote:
    > for (pch = strtok(str, ","); pch = strtok(NULL, ","); pch != NULL)


    You almost certainly meant to swap the last two expressions.

    for (a;b;c) {...} is equivilant to a; while (b) {{...} c;}

    > while(!feof(fPtr))


    This is generally quite a bad idea in C; in your case...

    > {
    > fgets(str,288,fPtr);


    A file ending with a new-line character will loop once more, but is
    already at the end of the file; str is untouched and you repeat the
    processing, which is probably not what you want.

    while(fgets(str, 288, fPtr)) might be more appropriate.

    > str[strlen(str)-1]=0;


    If the file does not end with a new-line character, this drops what
    would've been the last character of the line; a check that the last
    character is a new-line before overwriting it or that feof(fPtr) is
    not true will prevent such behaviour.

    > return 1;


    You might like to change this to EXIT_FAILURE, from <stdlib.h>, for
    a portable interpretation.

    --
    ++acr@,ka"
     
    Sam Dennis, Apr 11, 2004
    #2
    1. Advertising

  3. Ram Laxman

    Al Bowers Guest

    Ram Laxman wrote:
    > Hi all,
    > I have written the following code:
    >
    >
    > /* strtok example */
    > #include <stdio.h>
    > #include <string.h>
    >
    > static const char * const resultFileName = "param.txt";
    >
    > int main ()
    > {
    >
    > FILE *fPtr;
    > char str[300];
    > char * pch;
    > int len;
    > char savedstr[300];
    >
    > fPtr =fopen(resultFileName, "r");
    >
    > if(fPtr == NULL)
    > {
    > printf("File doesnot exist");
    > return 1;
    > }
    >
    > else
    > {
    > while(!feof(fPtr))
    > {
    > fgets(str,288,fPtr);
    > len = strlen(str);
    > str[len-1]=0;
    > for ( (pch=strtok(str,","));(pch = strtok(NULL,","));(pch
    > !=NULL))
    > {
    > strncpy(savedstr,pch,len);
    > printf("Saved String =%s\n",savedstr);
    > }
    >
    >
    > }
    >
    > }
    >
    > fclose(fPtr);
    > return 0;
    >
    > }
    >
    > I have a text file as the following:
    > param.txt:
    >
    > "ram","lax","deepak"
    > 10,20,30
    > 40,80,100
    > 70,90,100
    > and so on...
    >
    > When I use strtok(delim ,) the problem is that the string "ram" never
    > gets stored in savedstr array while from "lax" onwards it gets stored.
    >
    > 1.Could any body suggest a better method so that I can store "ram"
    > also in the saved string and tokenize based on comma separated
    > delimiter?
    >


    The method you are using is not bad although I personally don't
    like using fixed sizes like str[300], savedstr[300] when you are
    storing into them data from a file. However, using these fixed
    sizes makes the coding easier(IMO). The major problems in your
    code is that you need to change the declaraion of savedstr to something
    like char savedstr[MAXSTRINGS][MAXPARM+1] where the macros have
    been appropriated defined. Also, you loop using feof is not
    neccessary. You can loop with function fgets. fgets will return
    NULL should the end of the file be encountered and there have
    been no characters read into the character array.

    To salvage your code make these changes mentioned:

    /* strtok example */
    #include <stdio.h>
    #include <string.h>

    #define MAXLINE 100
    #define MAXSTRINGS 300
    #define MAXPARM 30

    static const char * const resultFileName = "param.txt";

    int main (void)
    {
    FILE *fPtr;
    char str[MAXLINE];
    char * pch;
    size_t i, count;
    char savedstr[MAXSTRINGS][MAXPARM+1];

    fPtr =fopen(resultFileName, "r");

    if(fPtr == NULL)
    {
    printf("File doesnot exist");
    return 1;
    }
    for(count = 0; (fgets(str,288,fPtr)) && count != MAXSTRINGS; )
    for (pch=strtok(str,",");pch; pch = strtok(NULL,","))
    {
    strncpy(savedstr[count],pch,MAXPARM);
    savedstr[count++][MAXPARM] = '\0';
    }
    fclose(fPtr);
    for(i = 0 ;i < count;i++)
    printf("savedstr[%u] = %s\n",i,savedstr);
    return 0;
    }


    > 2.Is there anything in C like (map in C++) so that I can store:
    >
    > (key)
    > "ram"---->10,40,70(In an array of integer values)
    > "lax"---->20,80,90
    >
    > Could anybody help me in this regard?
    >


    This makes the code a little more complicated. You should
    probably create datatypes to store the data parsed from the file.
    The actucal code depends on how the data is stored in the file.
    In the following example, the contents in param.txt is:
    "ram",10,20,30
    "lax",40,80,100,500
    "deepak",70,90,100,30,11

    And the code(little tested) to parse the data in the file gives
    the output:
    Parm Name is "ram"
    The values are: 10 20 30

    Parm Name is "lax"
    The values are: 40 80 100 500

    Parm Name is "deepak"
    The values are: 70 90 100 30 11

    The code:
    /* strtok example */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    #define MAXLINE 100
    #define MAXPARM 30

    typedef struct PARM
    {
    char parmname[MAXPARM+1];
    int *parmvalue;
    size_t valuecount;
    } PARM;

    typedef struct PARM_ARR
    {
    PARM *parm;
    size_t parmcount;
    } PARM_ARR;

    PARM init;

    int parseline(PARM_ARR *p, FILE *fp);
    void freePARM_ARR(PARM_ARR *p);
    void printPARM( PARM *p);

    static const char * const resultFileName = "param.txt";

    int main (void)
    {
    FILE *fPtr;
    size_t i;
    PARM_ARR my = {NULL};

    fPtr =fopen(resultFileName, "r");
    if(fPtr == NULL)
    {
    printf("File doesnot exist");
    return 1;
    }
    while(parseline(&my,fPtr)) ;
    fclose(fPtr);
    for(i = 0; i < my.parmcount; i++)
    printPARM(&my.parm);
    freePARM_ARR(&my);
    return 0;
    }

    int parseline(PARM_ARR *p, FILE *fp)
    { /* TODO: write more robust code to validate file data */
    char *s,buf[MAXLINE];
    size_t count;
    PARM *tmp;
    int *itmp;

    while(1)
    { /* skip empty? line */
    if(!fgets(buf,sizeof buf,fp)) return 0;
    if(*buf != '\n') break;
    }
    tmp = realloc(p->parm,(p->parmcount+1)*(sizeof *tmp));
    if(!tmp) return 0;
    p->parm = tmp;
    p->parm[p->parmcount] = init;
    for(count = 0,s = strtok(buf,","); s ;
    s = strtok(NULL,","), count++)
    {
    if(count == 0)
    {
    strncpy(p->parm[p->parmcount].parmname,s,MAXPARM);
    p->parm[p->parmcount].parmname[MAXPARM] = '\0';
    }
    else
    {
    itmp = realloc(p->parm[p->parmcount].parmvalue,
    (p->parm[p->parmcount].valuecount+1)*(sizeof *itmp));
    if(!itmp) return 0;
    p->parm[p->parmcount].parmvalue = itmp;
    p->parm[p->parmcount].parmvalue[p->parm[p->parmcount].
    valuecount++] =(int)strtol(s,NULL,10);
    }
    }
    p->parmcount++;
    return 1;
    }

    void freePARM_ARR(PARM_ARR *p)
    {
    size_t i;

    for(i = 0;i < p->parmcount;i++)
    free(p->parm.parmvalue);
    free(p->parm);
    p->parm = NULL;
    p->parmcount = 0;
    return;
    }
    void printPARM( PARM *p)
    {
    size_t i;

    printf("Parm Name is %s\nThe values are: ", p->parmname);
    for(i = 0;i < p->valuecount;i ++)
    printf("%d ",p->parmvalue);
    puts("\n");
    return;
    }



    --
    Al Bowers
    Tampa, Fl USA
    mailto: (remove the x to send email)
    http://www.geocities.com/abowers822/
     
    Al Bowers, Apr 11, 2004
    #3
  4. Ram Laxman

    Ram Laxman Guest

    Thanks Al Bowers,

    But I see I could able to store only "A"--->10,40. But could not able to store
    "B"---->20,80 and "C"-->30,100 in the array.

    Regards
    Ram Laxman


    Al Bowers <> wrote in message news:<c5bqkv$2qsqgd$-berlin.de>...
    > Ram Laxman wrote:
    > > Hi all,
    > > I have written the following code:
    > >
    > >
    > > /* strtok example */
    > > #include <stdio.h>
    > > #include <string.h>
    > >
    > > static const char * const resultFileName = "param.txt";
    > >
    > > int main ()
    > > {
    > >
    > > FILE *fPtr;
    > > char str[300];
    > > char * pch;
    > > int len;
    > > char savedstr[300];
    > >
    > > fPtr =fopen(resultFileName, "r");
    > >
    > > if(fPtr == NULL)
    > > {
    > > printf("File doesnot exist");
    > > return 1;
    > > }
    > >
    > > else
    > > {
    > > while(!feof(fPtr))
    > > {
    > > fgets(str,288,fPtr);
    > > len = strlen(str);
    > > str[len-1]=0;
    > > for ( (pch=strtok(str,","));(pch = strtok(NULL,","));(pch
    > > !=NULL))
    > > {
    > > strncpy(savedstr,pch,len);
    > > printf("Saved String =%s\n",savedstr);
    > > }
    > >
    > >
    > > }
    > >
    > > }
    > >
    > > fclose(fPtr);
    > > return 0;
    > >
    > > }
    > >
    > > I have a text file as the following:
    > > param.txt:
    > >
    > > "ram","lax","deepak"
    > > 10,20,30
    > > 40,80,100
    > > 70,90,100
    > > and so on...
    > >
    > > When I use strtok(delim ,) the problem is that the string "ram" never
    > > gets stored in savedstr array while from "lax" onwards it gets stored.
    > >
    > > 1.Could any body suggest a better method so that I can store "ram"
    > > also in the saved string and tokenize based on comma separated
    > > delimiter?
    > >

    >
    > The method you are using is not bad although I personally don't
    > like using fixed sizes like str[300], savedstr[300] when you are
    > storing into them data from a file. However, using these fixed
    > sizes makes the coding easier(IMO). The major problems in your
    > code is that you need to change the declaraion of savedstr to something
    > like char savedstr[MAXSTRINGS][MAXPARM+1] where the macros have
    > been appropriated defined. Also, you loop using feof is not
    > neccessary. You can loop with function fgets. fgets will return
    > NULL should the end of the file be encountered and there have
    > been no characters read into the character array.
    >
    > To salvage your code make these changes mentioned:
    >
    > /* strtok example */
    > #include <stdio.h>
    > #include <string.h>
    >
    > #define MAXLINE 100
    > #define MAXSTRINGS 300
    > #define MAXPARM 30
    >
    > static const char * const resultFileName = "param.txt";
    >
    > int main (void)
    > {
    > FILE *fPtr;
    > char str[MAXLINE];
    > char * pch;
    > size_t i, count;
    > char savedstr[MAXSTRINGS][MAXPARM+1];
    >
    > fPtr =fopen(resultFileName, "r");
    >
    > if(fPtr == NULL)
    > {
    > printf("File doesnot exist");
    > return 1;
    > }
    > for(count = 0; (fgets(str,288,fPtr)) && count != MAXSTRINGS; )
    > for (pch=strtok(str,",");pch; pch = strtok(NULL,","))
    > {
    > strncpy(savedstr[count],pch,MAXPARM);
    > savedstr[count++][MAXPARM] = '\0';
    > }
    > fclose(fPtr);
    > for(i = 0 ;i < count;i++)
    > printf("savedstr[%u] = %s\n",i,savedstr);
    > return 0;
    > }
    >
    >
    > > 2.Is there anything in C like (map in C++) so that I can store:
    > >
    > > (key)
    > > "ram"---->10,40,70(In an array of integer values)
    > > "lax"---->20,80,90
    > >
    > > Could anybody help me in this regard?
    > >

    >
    > This makes the code a little more complicated. You should
    > probably create datatypes to store the data parsed from the file.
    > The actucal code depends on how the data is stored in the file.
    > In the following example, the contents in param.txt is:
    > "ram",10,20,30
    > "lax",40,80,100,500
    > "deepak",70,90,100,30,11
    >
    > And the code(little tested) to parse the data in the file gives
    > the output:
    > Parm Name is "ram"
    > The values are: 10 20 30
    >
    > Parm Name is "lax"
    > The values are: 40 80 100 500
    >
    > Parm Name is "deepak"
    > The values are: 70 90 100 30 11
    >
    > The code:
    > /* strtok example */
    > #include <stdio.h>
    > #include <string.h>
    > #include <stdlib.h>
    >
    > #define MAXLINE 100
    > #define MAXPARM 30
    >
    > typedef struct PARM
    > {
    > char parmname[MAXPARM+1];
    > int *parmvalue;
    > size_t valuecount;
    > } PARM;
    >
    > typedef struct PARM_ARR
    > {
    > PARM *parm;
    > size_t parmcount;
    > } PARM_ARR;
    >
    > PARM init;
    >
    > int parseline(PARM_ARR *p, FILE *fp);
    > void freePARM_ARR(PARM_ARR *p);
    > void printPARM( PARM *p);
    >
    > static const char * const resultFileName = "param.txt";
    >
    > int main (void)
    > {
    > FILE *fPtr;
    > size_t i;
    > PARM_ARR my = {NULL};
    >
    > fPtr =fopen(resultFileName, "r");
    > if(fPtr == NULL)
    > {
    > printf("File doesnot exist");
    > return 1;
    > }
    > while(parseline(&my,fPtr)) ;
    > fclose(fPtr);
    > for(i = 0; i < my.parmcount; i++)
    > printPARM(&my.parm);
    > freePARM_ARR(&my);
    > return 0;
    > }
    >
    > int parseline(PARM_ARR *p, FILE *fp)
    > { /* TODO: write more robust code to validate file data */
    > char *s,buf[MAXLINE];
    > size_t count;
    > PARM *tmp;
    > int *itmp;
    >
    > while(1)
    > { /* skip empty? line */
    > if(!fgets(buf,sizeof buf,fp)) return 0;
    > if(*buf != '\n') break;
    > }
    > tmp = realloc(p->parm,(p->parmcount+1)*(sizeof *tmp));
    > if(!tmp) return 0;
    > p->parm = tmp;
    > p->parm[p->parmcount] = init;
    > for(count = 0,s = strtok(buf,","); s ;
    > s = strtok(NULL,","), count++)
    > {
    > if(count == 0)
    > {
    > strncpy(p->parm[p->parmcount].parmname,s,MAXPARM);
    > p->parm[p->parmcount].parmname[MAXPARM] = '\0';
    > }
    > else
    > {
    > itmp = realloc(p->parm[p->parmcount].parmvalue,
    > (p->parm[p->parmcount].valuecount+1)*(sizeof *itmp));
    > if(!itmp) return 0;
    > p->parm[p->parmcount].parmvalue = itmp;
    > p->parm[p->parmcount].parmvalue[p->parm[p->parmcount].
    > valuecount++] =(int)strtol(s,NULL,10);
    > }
    > }
    > p->parmcount++;
    > return 1;
    > }
    >
    > void freePARM_ARR(PARM_ARR *p)
    > {
    > size_t i;
    >
    > for(i = 0;i < p->parmcount;i++)
    > free(p->parm.parmvalue);
    > free(p->parm);
    > p->parm = NULL;
    > p->parmcount = 0;
    > return;
    > }
    > void printPARM( PARM *p)
    > {
    > size_t i;
    >
    > printf("Parm Name is %s\nThe values are: ", p->parmname);
    > for(i = 0;i < p->valuecount;i ++)
    > printf("%d ",p->parmvalue);
    > puts("\n");
    > return;
    > }
     
    Ram Laxman, May 3, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. strtok problem

    , Aug 28, 2003, in forum: C Programming
    Replies:
    4
    Views:
    517
  2. collinm

    strtok problem - strcmp

    collinm, Mar 24, 2005, in forum: C Programming
    Replies:
    4
    Views:
    808
    Mark McIntyre
    Mar 24, 2005
  3. Replies:
    3
    Views:
    507
    Steven Kobes
    Jul 27, 2005
  4. ern

    strtok() problem

    ern, Sep 20, 2005, in forum: C Programming
    Replies:
    12
    Views:
    644
    Default User
    Sep 22, 2005
  5. strtok problem

    , Mar 29, 2006, in forum: C Programming
    Replies:
    6
    Views:
    440
    CBFalconer
    Mar 31, 2006
Loading...

Share This Page