strtok
returns either a null pointer, or a pointer to a NUL-terminated byte sequence (i.e., a valid C string).
Your token = token + '\0';
isn't doing what you (almost certainly) think. Since token
is a pointer (that's the return type from strtok
) it's doing pointer arithmetic. Fortunately, '\0'
is a long-winded way of saying 0
(trivia of the moment: character literals in C have type int
, not type char
), so at least it's not changing the pointer.
Check the value being returned by strtok
. If you second strcpy
is failing, it's probably because strtok
is failing and returning a null pointer.
That said, given that you're using a single fixed string to define your delimiters, you can probably do the job a lot easier (and more cleanly) with sscanf
. For example, if s
contains ,.-+
, you could use:
sscanf(input, "%1[^,.-+]%*c%9[^,.-+]", update, firstname);
I've ignored the third call to strtok
for now, because you're never copying from its return value to a destination (but repeating the pattern above will work for more variables, of course). Note the use of the number between the %
and the scan set ([^...]
). You always want to specify the size of buffer when using %s
or %[...]. The size you specify should always be one smaller than the buffer into which you're having them write (because they always append a trailing
'\0'`).
On the off chance that s
is actually a string you read from an external source (or something on that order, so you can't easily put its contents into a string literal) you can synthesize your format string at run-time if needed:
char template[] = "%%[^%s]%%*c%%[^%s]";
char format[512];
sprintf(format, template, s, s);
sscanf(input, format, update, firstname);
[Though format strings are most often literals, that's not required.]
Edit: I don't think you'd originally linked the code, but it reveals at least one problem: char update[1];
. Using this as a target of strcpy
is a problem because it always appends a trailing '\0'
to terminate the string. In this case you've allocated only a single character, so you only have room for the terminator, not any actual data. You need to expand it out to at least two characters. Given that you're copying into fixed-size buffers, you probably want to either check that the string will fit into your buffer before copying, or else use something to copy that limits the size of data it'll copy (and still always includes a terminator, unlike strncpy
).