Thread: Trouble with Strtok function

  1. #1
    Registered User
    Join Date
    Mar 2017
    Posts
    12

    Trouble with Strtok function

    Hello, I have the following code below:

    Code:
    #include <ansi_c.h>
    #include<stdio.h>
    
    
    int main(void)
    {
        FILE *in;
    
    
        int size;
    
    
        char *data;
        char *tokenPtr;
    
    
        
        in=fopen("filename.txt","r");
    
    
        fseek(in,0,SEEK_END);
        size=ftell(in);
        rewind(in);
        
        data=(char*)malloc(size*sizeof(char));
          
        
        fread(data,sizeof(char),size,in);
        fclose(in);
        
        tokenPtr=strtok(data,",");
        
        while(tokenPtr != NULL)
        {
            printf("%s\n",tokenPtr);
            tokenPtr = strtok(NULL, ",");
        }
        
        free(data);
    
    
        return(0);
        
    }
    When I try to run the code, it gives me the following error: "Missing terminating null in string argument."

    Any ideas on how to fix this issue?

    Thanks!

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Yeah, the fread() function does not guarantee that data will be terminated with a '\0' like a string. Replace malloc().

    Code:
     data = calloc(size, sizeof(char));
    Now it will be terminated.

  3. #3
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    whiteflags forgot to add 1 to the size.
    And it's pointless to say sizeof(char) since it's always 1 by definition
    Better to say:
    Code:
    data = calloc(size + 1, sizeof *data);

    That way it will still work if data is changed to be wchar or something else.

    However, I'm not sure if the fseek-to-end, ftell idiom is entirely correct unless you specify binary mode. In that case you may want to use ",\r\n" for your strtok delimiters.

    I have no idea what ansi_c.h is. Try commenting it out and adding the standard includes for stdlib.h (for malloc and free) and string.h (for strtok).

    Also, you should ensure that the file actually opened. in will be NULL if it didn't open.

    BTW, what system/compiler are you using?

  4. #4
    Registered User
    Join Date
    Mar 2017
    Posts
    12
    Thank you!

  5. #5
    Registered User
    Join Date
    Mar 2017
    Posts
    12
    Quote Originally Posted by algorism View Post
    whiteflags forgot to add 1 to the size.
    And it's pointless to say sizeof(char) since it's always 1 by definition
    Better to say:
    Code:
    data = calloc(size + 1, sizeof *data);

    That way it will still work if data is changed to be wchar or something else.

    However, I'm not sure if the fseek-to-end, ftell idiom is entirely correct unless you specify binary mode. In that case you may want to use ",\r\n" for your strtok delimiters.

    I have no idea what ansi_c.h is. Try commenting it out and adding the standard includes for stdlib.h (for malloc and free) and string.h (for strtok).

    Also, you should ensure that the file actually opened. in will be NULL if it didn't open.

    BTW, what system/compiler are you using?
    Thank you!! I just have a few more questions if you don't mind. Why does calloc work, yet malloc doesn't?

    And I'm just a bit confused about your comment on the fseek-to-end and the strtok delimiters. Do you mean it's not the correct way to find the size of my file?

    I'm using Labwindows CVI. I believe Labwindows automatically includes all of those standard librarys in the ansi_c.h.

    Thanks again for answering, I'm pretty new to c programming so I appreciate all the help!

  6. #6
    Registered User
    Join Date
    Mar 2017
    Posts
    12
    Sorry one more question, why is it necessary to add 1 to the size in the calloc function?

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Do you know the difference between calloc and malloc? Do you know that C strings need to be zero-terminated? That should answer your questions.

    As for fseek, I'm unsure exactly how it works in text mode with Windows text files, which end lines with two bytes: 0x0d ('\r'), 0x0a ('\n'). When reading in text mode the 0x0d ('\r') bytes will be thrown out (i.e., not stored in the buffer). Still, I suppose that ftell would overestimate the needed size so it shouldn't be a problem.

    Anyway, you didn't answer my question in your other post about the exact form of the input file and the data structure you want to read it in to.

  8. #8
    Registered User
    Join Date
    Mar 2017
    Posts
    12
    Calloc initializes the allocated memory to 0, got it! So are you adding 1 to the size so that the last bit in the array will contain the zero to terminate the string?

    Sorry about that! I'm reading in a CSV file. I'm using the commas as delimiters in the strtok function and then storing the locations of the tokens in an array.

  9. #9
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    The last byte (not bit!) in the char array, yes.

    Simply saying "CSV" file doesn't tell me the whole structure.

    Is it one big line with comma-separated tokens (and no commas that aren't delimiters) and no newline at the end of the line? Even if there's a newline at the end of the gigantic line you may need to add that to your delimiters (unless you want it to be part of the last token).

    More likely, it's multiple lines, possibly with the same number of tokens on each line, possibly even with the different tokens representing elements in a record. So you probably want to add newline to your delimiters.

    John,123,alpha
    Bob,456,beta
    Dave the Destroyer,789,gamma

    Are there extra spaces you might want eliminated? Are there any escaped commas (that therefore aren't delimiters)? Anyway, you get the idea.

    And I'm unsure what you mean by the "locations" of the tokens. More generally, I don't know how you want to store the data in your program. For the above example file, you may want to only store a single record at a time, perhaps with the number as an int. Or you may want to read the entire thing into an array of structs. That's the kind of thing I was asking about.

    Anyway, you may want to work on and post the next version of your program.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 05-02-2013, 11:26 PM
  2. strtok function
    By Omnipotent in forum C Programming
    Replies: 7
    Last Post: 04-03-2011, 08:12 PM
  3. New to C trouble with strtok and storing the values
    By robin2aj in forum C Programming
    Replies: 5
    Last Post: 03-18-2010, 06:52 AM
  4. strtok function
    By hello124 in forum C++ Programming
    Replies: 8
    Last Post: 04-23-2005, 06:58 AM
  5. Trouble with strtok()
    By BianConiglio in forum C Programming
    Replies: 2
    Last Post: 05-08-2004, 06:56 PM

Tags for this Thread