Mike -- No longer here
Mike -- No longer here

Reputation: 2092

extracting data between two semicolons in C

I'm trying to write a utility type of function without being too complex to extract a value from semicolon separated strings. In this example, I'm trying to extract X=bc and what I receive instead is a segmentation fault when assigning a value to *cpp

What could I be doing wrong?

int main()
{
    char x[500]="a;X=bc;def;ghi";
    char* cp=x,*cpp;

    while ((cp=strstr(cp,";")))
    {
        cp++;

        if ((*cp)=='X' && (*cp+1)=='=')
        {
            cp+=2;
            break;
        }
    }

    if ((cpp=strstr(cp,";")))
    {
        *cpp='\0';
    }

    printf("'%s' '%s'\n",x,cp);
    return 0;
}

Upvotes: 2

Views: 149

Answers (3)

Daniel Kamil Kozar
Daniel Kamil Kozar

Reputation: 19306

You might want to look into using the standard library function, strtok, which sounds like a perfect fit for this task. It takes a string and separates it into tokens, based on the delimiter or delimiters given as a parameter.

This code should get you started :

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

int main(void)
{
        char *token;
        char *parsed;
        char input[] ="a;X=bc;def;ghi";
        parsed = input;
        while(token = strtok(parsed, ";"))
        {
                parsed = NULL;
                puts(token);
        }
        return 0;
}

The first call to strtok uses the actual string to be parsed as the first parameter, while the following calls use NULL. If there are no more tokens (or no tokens at all), strtok returns NULL.

There are a few things to keep in mind when using this function, though :

  1. The prototype is char *strtok(char *str, const char *delim);. This means that str must be writable. As such, you must not assume that it will be left unmodified.
  2. If you're ever going to use threads in your program, calling strtok from multiple threads will lead to bugs, since it uses global state to store the last returned token. POSIX defines a thread-safe form of this function whose prototype is char *strtok_r(char *str, const char *delim, char **saveptr);, with the last parameter used to store data between calls. With such an interface, there is no need to use global state, as saveptr can be stored as a local variable.

The documentation for this function should answer all your further doubts.

Upvotes: 1

Michi
Michi

Reputation: 5297

Because you got your answer I only can show you another approach:

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

void checkString(char *string1, char *string2){
    char *string3;
    char *s1, *s2, *s3;

    size_t lenstring1 = strlen(string1);
    size_t lenstring2 = strlen(string2);

    if (lenstring2 < 1){
        printf("There is no substring found");
        exit(1);
    }

    size_t i=0,j=0;
    int found=0;

    s1 = string1;
    s2 = string2;


    for(i = 0; i < lenstring1; i++){
        if(*s1 == *s2){
            s3 = s1;
            for(j = 0;j < lenstring2;j++){
                if(*s3 == *s2){
                  s3++;s2++;
                }else{
                    break;
                }
            }

            s2 = string2;
            if(j == strlen(string2)){
                found = 1;
                string3=string2;
              }
          }
        s1++;
    }

    if(found != 0){
        printf("%s\n",string3);

    }else{
        printf("No match Found");
    }
}

int main(void){
    char string1[] = "a;X=bc;def;ghi";
    char string2[] = "X=bc";

    checkString(string1, string2);
    return 0;
}

Output:

X=bc

Upvotes: 1

Paul R
Paul R

Reputation: 213059

This line is wrong:

    if ((*cp)=='X' && (*cp+1)=='=')

it should be:

    if ((*cp)=='X' && *(cp+1)=='=')

or better yet:

    if (cp[0]=='X' && cp[1]=='=')

Note that the code as written is very fragile - there are many ways in which it can fail - try and get into the habit of programming defensively - always assume that anything that can fail will fail and write your code accordingly, so that it will at least fail gracefully when things don't work as expected.

Another tip, while I'm here: learn some basic debugging techniques - I couldn't immediately see what was wrong with the code so I added a few printf's to the code so that I could get more information about what was going on - it soon became apparent that cp was NULL after the first loop and from there it was easier to see the problem. Alternatively I could have just stepped through the code in a debugger - either technique would take you straight to this bug in a minute or two.

Upvotes: 3

Related Questions