user2684719
user2684719

Reputation:

C String split and print the tokens.

I am trying to split the string and print the tokens.

int main()
{
    char line[255] = "182930101223, KLA1513";
    char val1[16];
    char val2[7];

    strcpy(val1, strtok(line, ","));
    strcpy(val2, strtok(NULL, ","));

    printf("%s|%s\n", val1, val2);

    return 0;
}

When I print I get

  3| KLA1513

instead of

182930101223| KLA1513

What is the issue?

Upvotes: 2

Views: 1299

Answers (2)

meaning-matters
meaning-matters

Reputation: 22946

Try this:

#include <stdio.h>
#include <string.h>

int main()
{
    char line[] = "182930101223, KLA1513";
    char* val1;
    char* val2;

    val1 = strtok(line, ",");
    val2 = strtok(NULL, ",");

    printf("%s|%s\n", val1, val2);

    return 0;
}

There is no need to strcpy() the tokens, you can just use char*; strtok() will add a closing \0 at the end of each token found.

It's also safer, because you don't need to know the size of the tokens beforehand; and size of your tokens was the problem. If you do need to have the token in their own memory, you can copy them into sufficiently sized strings afterwards.

Note that we can't do:

char* line = "182930101223, KLA1513";

because strtok() modifies the string, and it's not allowed to modify a literal C string.

Upvotes: 2

Dave
Dave

Reputation: 46259

OK, I thought this was an unrelated issue, but I now think it is the issue you are seeing.

It's important to remember that C strings take 1 extra character than they contain. This is the terminating NUL character (\0), and marks the end of the text.

So KLA1513 is actually 8 characters (KLA1513\0). Additionally, because you are not trimming spaces, it is 9 characters! _KLA1513\0 (_ is a space).

That means that you're overrunning the memory in your second strcpy, leading to undefined behaviour, which (you will come to realise) is your worst nightmare.

When you print it, who knows what state the program is in. Maybe the memory you overwrote was part of the print call, or maybe it was overwritten again and now var2 isn't terminated.

Just make var2 bigger (9 characters is enough here), and in future, use the safe forms (strncpy, for example). Mistakes like this are how hackers usually manage to compromise systems.

Upvotes: 7

Related Questions