strtok causing segfault but not when step through code
Asked Answered
P

1

-1

I am new to C and I am trying to split a date/time string into separate variables. However, when I step through the code in gdb line by line, it works, however, when I let it run through normally without breakpoints it seg faults and I can't see why.

Below is the code:

char * dateTimeString = "2011/04/16 00:00";
char dateVar[11];
char timeVar[6];

if (splitTimeAndDateString(dateVar, timeVar, dateTimeString))
{
    exit(1);
}

printf("Date: %s\tTime: %s\n", dateVar, timeVar);

Below is the function

int splitTimeAndDateString(char date[11], char time[6], char * dateString)
{
    char *token;
    token = strtok(dateString, " ");
    int i = 0;
    while (token != NULL)
    {
        if (i == 0)
        {
            strcpy(date, token);
        }
        else if (i == 1)
        {
            strcpy(time, token);
        }
        else
        {
            printf("Overrun date time string\n");
            return 1;
        }
        token = strtok(NULL, " ");
        i++;
    }
    return 0;
}

Thanks for any help you can provide.

Pentachlorophenol answered 9/7, 2013 at 15:3 Comment(12)
Not the cause of your issue, but I'd pass all pointers, like this int splitTimeAndDateString(char *date, char *time, char *dateString)Siege
char * dateTimeString = "2011/04/16 00:00"; - you don't seem to be understanding why string literals are sometimes called string constants. const char *dateTimeString is the only appropriate declaration.Wine
Oh, and this is a dupe (out of the other 10000000 ones.)Wine
possible duplicate of Strtok segfaultWine
And of strtok segmentation fault too.Wine
And of strtok giving Segmentation Fault as well.Wine
I strongly advise learners to read K&R. Strongly advise. Strings and pointers are basic C concepts. Very basic.Jenisejenkel
And if that's not enough, of Problem with strtok and segmentation fault too.Wine
@Jenisejenkel Please make that "very basic" bold and italics.Wine
(By the way, the four duplicates are literally the first four Google hit for "strtok segfault". I simply don't understand how come one does not start by googling the concatenation of the error message and the name of the suspicious function. That always works. And then you don't have to ask a bad duplicate question on Stack Overflow and loose your hard-earned rep...)Wine
In fact, I pointed out this in *comments * in one of the answers to this question : #17500171Glisten
codepad.org/mHbtXYtTSvensen
S
9

The strtok() function modifies string that you wants to parse, and replace all delimiters with \0 nul symbol.

Read: char * strtok ( char * str, const char * delimiters );

str
C string to truncate.
Notice that the contents of this string are modified and broken into smaller strings (tokens). Alternativelly, a null pointer may be specified, in which case the function continues scanning where a previous successful call to the function ended.

In your code:

 strtok(dateString, " "); 
           ^
           |  is a constant string literal 

dateString points to "2011/04/16 00:00" a constant string literal, and by using strtok() your code trying to write on read-only memory - that is illegal and this caused segmentation fault.

Read this linked answer for diagram to understand: how strtok() works?

Edit:

@: char * strtok ( char * str, const char * delimiters ); In given code example, str is an array, not constant string literal. Its declaration:

char str[] ="- This, a sample string.";

Here str[] is an nul terminated array of chars, that initialized with string and its length is equals to size of the assigned string. You can change the content of str[] e.g. str[i] = 'A' is a valid operation.

Whereas in your code:

char * dateTimeString = "2011/04/16 00:00"; 

dateTimeString is pointer to string literal that is not modifiable e.g dateTimeString[i] = 'A' is an illegal operation this time.

Svensen answered 9/7, 2013 at 15:8 Comment(7)
I'm not what you mean, I took the example from cplusplus.com/reference/cstring/strtok. I use dateString in the strToke on the first call, then on the second call within the while loop I use strtok(NULL, " ")Pentachlorophenol
@Pentachlorophenol here char str[] ="- This, a sample string."; is array not a const stringSvensen
@Pentachlorophenol yes strtok tries to divide the dataString in tokens while it is a constant string literal which is not modifiable. And there is a difference between str[] and *str.Glisten
Oh OK, now I understand, I've changed it as per @GrijeshChauhan answer he linked to another question where I copy the contents of dateString into a temp variable and use that, which does seem to work, exception after I return and the printf is executed, I then receive an abort even though the print successfully workedPentachlorophenol
I did not know this :-) Thanks. From the man page, we have "This end of the token is automatically replaced by a null-character, and the beginning of the token is returned by the function.....The point where the last token was found is kept internally by the function to be used on the next call (particular library implementations are not required to avoid data races).".Aetna
@Pentachlorophenol It shouldn't about, I compiled the code with gcc -Wall -pedantic and couldn't find and warning, additionally you code working fine on Codepade after the rectification I suggested.Svensen
@GrijeshChauhan, Yea it is working now, not sure what happened, about 5 mins after I got the abort the server locked up and needed a restart and now its working. It is a bit of an old unreliable so basing it was some odd issue with the server. Thanks for your help. Much appreciated.Pentachlorophenol

© 2022 - 2024 — McMap. All rights reserved.