-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.

jh314
  • 27,144
  • 16
  • 62
  • 82
Boardy
  • 35,417
  • 104
  • 256
  • 447
  • Not the cause of your issue, but I'd pass all pointers, like this `int splitTimeAndDateString(char *date, char *time, char *dateString)` – fvu Jul 09 '13 at 15:20
  • 2
    `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. –  Jul 09 '13 at 15:28
  • 2
    Oh, and this is a dupe (out of the other 10000000 ones.) –  Jul 09 '13 at 15:28
  • 5
    possible duplicate of [Strtok segfault](http://stackoverflow.com/questions/7100214/strtok-segfault) –  Jul 09 '13 at 15:29
  • 4
    And of [strtok segmentation fault](http://stackoverflow.com/questions/8957829/strtok-segmentation-fault) too. –  Jul 09 '13 at 15:29
  • 5
    And of [strtok giving Segmentation Fault](http://stackoverflow.com/questions/2385697/strtok-giving-segmentation-fault) as well. –  Jul 09 '13 at 15:29
  • 4
    I *strongly* advise learners to read K&R. *Strongly* advise. Strings and pointers are basic C concepts. Very basic. – PP. Jul 09 '13 at 15:30
  • 3
    And if that's not enough, of [Problem with strtok and segmentation fault](http://stackoverflow.com/questions/5925405/problem-with-strtok-and-segmentation-fault) too. –  Jul 09 '13 at 15:30
  • 4
    @PP. Please make that "very basic" bold and italics. –  Jul 09 '13 at 15:30
  • 2
    (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...) –  Jul 09 '13 at 15:36
  • In fact, I pointed out this in *comments * in one of the answers to this question : http://stackoverflow.com/questions/17499671/want-to-pass-a-single-char-pointer-from-a-double-pointer/17499878#comment25451523_17499878 – 0decimal0 Jul 09 '13 at 15:38
  • http://codepad.org/mHbtXYtT – Grijesh Chauhan Jul 09 '13 at 15:53

1 Answers1

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.

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • I'm not what you mean, I took the example from http://www.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, " ") – Boardy Jul 09 '13 at 15:11
  • @Boardy here `char str[] ="- This, a sample string.";` is array not a const string – Grijesh Chauhan Jul 09 '13 at 15:13
  • 1
    @Boardy 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`. – 0decimal0 Jul 09 '13 at 15:13
  • 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 worked – Boardy Jul 09 '13 at 15:16
  • 1
    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).". – lsk Jul 09 '13 at 15:17
  • @Boardy 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**](http://codepad.org/mHbtXYtT) after the rectification I suggested. – Grijesh Chauhan Jul 09 '13 at 15:52
  • 1
    @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. – Boardy Jul 09 '13 at 16:45