strtok

Discussion in 'Mac Programming' started by farmerdoug, Mar 30, 2011.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    If I input BD+05 378, the code knows what do to converting it to BD%2B+378 but if I enter vega, strtok returns vega and not NULL

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (int argc, const char * argv[]) {
    // http://simbad.u-strasbg.fr/simbad/sim-basic?Ident=vega&submit=SIMBAD+search 
    char *star, *path, *simbad, c, *token, plus = '+', *tmpstar;
    int offset, i;
    float Vmag;
    
    FILE *file;
    
    star = (char *)calloc(30, sizeof(char));
    tmpstar = (char *)calloc(30, sizeof(char));
    path = (char *)calloc(250, sizeof(char));
    simbad = (char *)calloc(250, sizeof(char));
    do
        {
       
        strcpy(path,"'http://simbad.u-strasbg.fr/simbad/sim-basic?Ident=");
    
        printf("input star name or q to quit:\n");
        i = 0;
        fscanf(stdin,"%c", &c);
        while (c != '\n')
            {
            star[i++] = c;
            fscanf(stdin,"%c", &c);
            }
        star[i] = '\0';    
      
        
        
        if ((token = strtok(star,&plus)) != NULL)
            {printf("%s\n", token);
            strcpy(tmpstar, token);
            strcat(tmpstar, "%2B");
            token = strtok(NULL,&plus);
            printf("%s\n", token);
            strcat(tmpstar, token);
            strcpy(star, tmpstar);
            }
       
        i= 0;
        while (star[i++] != '\0')
            if (star[i-1] == ' ')
                star[i-1] = '+';
                                
    
         
        printf("%s\n", star);       
        if (strcmp(star,"q") == 0)
            return(99);
       
        strcat(path,star);
        strcpy(simbad, "curl ");
        strcat(simbad,path);
        strcat(simbad,"&submit=SIMBAD+search' > simbadout.txt ");
       
        system(simbad);
        strcpy(simbad,"grep \"<INPUT TYPE=\\\"hidden\\\" NAME=\\\"Coord\\\" VALUE=\\\"\" simbadout.txt > line.txt");
        system(simbad );
        if ((file = fopen("./line.txt", "r")) == NULL)
            printf("file not opened\n");
        
        fseek(file, 46, SEEK_SET);
        fgets(star,30,file);
        printf("%s\n",star);
        fclose(file);
        strcpy(simbad,"grep -b Fluxes simbadout.txt > line.txt");
        system(simbad );
         if ((file = fopen("./line.txt", "r")) == NULL)
            printf("file not opened\n");
        fscanf(file,"%d",&offset);
        printf("%d\n", offset);
         fclose(file);
         if ((file = fopen("./simbadout.txt", "r")) == NULL)
            printf("file not opened\n");
    
         fseek(file, offset, SEEK_SET);
       //   fgets(star,30,file);
       // printf("%s\n",star);
       // for (i = 0; i < 200; i++){
        fscanf(file,"%c", &c); 
    
         while (c != 'V')
            fscanf(file,"%c", &c); 
         
         fscanf(file,"%c", &c); 
        while (c != 'V')
            fscanf(file,"%c", &c);
         fscanf(file,"%c", &c);
    
        fscanf(file,"%s", star);
        printf("%s\n", star);
        
           
        
        
    
        }
    while(strcmp(star,"q") != 0);
        
    
     return (0);
    }
    
     
  2. gnasher729, Mar 30, 2011
    Last edited: Mar 30, 2011

    gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    The second argument of strtok must be a null-terminated C string. &plus is not a null-terminated C string, but just a pointer to a single character. That can cause all kind of trouble.

    Now if you _did_ pass "+" as the second argument, then you need to read the documentation of strtok carefully.

    The first call will skip all "+" characters, then return NULL if there was nothing but "+" characters (shouldn't happen).
    Then the first call returns either a string up to the first "+", or the complete string if there is no "+" afterwards.
    The second call will return NULL if there was no "+" found in the first call, or it returns a string from the first to the second "+" and so on.

    I suppose you would be happier using strchr or strstr to find the "+" character.
     
  3. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #3
    Maybe it can be more elegant but it works. Thanks.

    Code:
     
    
    char *plus;
    plus[0] = '+';
    plus[1] = '\0';
     strcpy(tmpstar,star);
     
        
        if ((token = strtok(star,plus)) != NULL)
            if(strcmp(token,tmpstar) != 0)
            {
            printf("%s\n", token);
            strcpy(tmpstar, token);
            strcat(tmpstar, "%2B");
            token = strtok(NULL,plus);
            printf("%s\n", token);
            strcat(tmpstar, token);
            strcpy(star, tmpstar); 
            }
    
    
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    It's not a question of elegance, but correctness. That code has a serious bug.

    char *plus; declares an uninitialized pointer.
    plus[0] = '+'; stores data at whatever the uninitialized pointer happens to be pointing at.
    plus[1] = '\0'; stores another byte of data, further obliterating some unknown memory location.

    Try this:
    Code:
    char *plus = "+";
    
     
  5. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #5
    I'm not exact sure what happened but the actual code reads
    char plus[2];

    but I like your coding better.
    thanks
     

Share This Page