Pete Darrow
Pete Darrow

Reputation: 455

Simpler way to extract occurrences without using strtok in C

I'm trying to extract the strings before and after the first comma from the given string. However, I feel there's got to be a better way than what I have below, perhaps I don't even need the strdup calls. Thanks

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

int extract_names(const char *str)
{
    char *name, *last, *p1, *p2, *p3;

    name = strdup(str);
    last = strdup(str);

    p1 = strchr(name, ',');
    if (p1)
    {
        *p1 = '\0';
        printf("%s\n", name);
    }

    p2 = strchr(last, ',');
    p2++;
    if (p2)
    {
        p3 = strpbrk(p2 + 1, " \0");
        if (p3)
            *p3 = '\0';
        printf("%s\n", p2);
    }
    free(name);
    free(last);

    return 0;
}

int main()
{
    // strings should at least contain last,name.
    // but can contain several words
    const char *str1 = "jones,bob age,12";
    extract_names(str1);
    const char *str2 = "smith,peter";
    extract_names(str2);
    return 0;
}

Output

jones
bob
smith
peter

Upvotes: 0

Views: 174

Answers (2)

kaylum
kaylum

Reputation: 14046

Use strchr to find the limits of the last and first names. Then you can use the precision specifier in printf to print just the part of the string you are interested in.

For example:

int extract_names(const char *str)
{
    const char *comma = strchr(str, ',');
    const char *name_end = strchr(str, ' ');

    /* name ends at space or end of string */
    if (!name_end) {
        name_end = str + strlen(str);
    }

    /* print last name */
    printf("%.*s\n", (comma - str), str);

    /* print first name */
    printf("%.*s\n", name_end - comma, comma + 1);

    return 0;
}

Upvotes: 1

Amit
Amit

Reputation: 46323

Since you're obviously trying to learn, I'll only give you a few pointers and not a "better working solution".

strdup is a useful idea here. As you do, it allows you to overwrite the string (const char *str is "readonly").

This combination:

p2 = strchr(last, ',');
p2++;
if (p2) {

is wrong. after the call p2 equals the return value. if you advance it before the if, you're not testing anything (if NULL was returned, it's 1 by the time you test it).

You don't need two strdups, and you don't need to search twice. p1 already points to the right place in name, you can use that for the rest of your logic.

Upvotes: 0

Related Questions