Reputation: 2092
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
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 :
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.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
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
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