Suppose my string is: haha "lol"
I want to extract only lol
#include<stdio.h>
int main() {
char a[20]={0};
char *s="haha \"lol\"";
if(sscanf(s,"%*[^\"]'%[^\"]\"",a)==1){
printf("Found stuff inside quotes");
}
}
Suppose my string is: haha "lol"
I want to extract only lol
#include<stdio.h>
int main() {
char a[20]={0};
char *s="haha \"lol\"";
if(sscanf(s,"%*[^\"]'%[^\"]\"",a)==1){
printf("Found stuff inside quotes");
}
}
By applying a proper parser for the source language that you are parsing.
One-liners for parsing input are often fragile and hard get right.
That said, you can try with something like
const char *input = "haha \"lol\"";
char quoted[32];
if(sscanf(input, "%*[^\"]\"%31[^\"]\"", quoted) == 1)
{
printf("got '%s'\n", quoted);
}
This should be hardened but is enough to get you started.
Sometimes a little code goes a long way. All that is need is 2 calls to strchr()
extract_quoted_string()
changed to pseudo-code.
const char *extract_quoted_string(const char *s, size_t *sz) {
const char *left = look_for_quote_start_at_s;
if (failure?) {
return NULL;
}
Update_left_to_the_next_possible_position
const char *right = look_for_quote_start_at_updated_left;
if (failure?) {
return NULL;
}
Compute_and_save_size_based_on_left_and_right
return left;
}
Test harness
void test(const char *s) {
printf("<%s> --> ", s);
size_t sz;
const char *extract = extract_quoted_string(s, &sz);
if (extract) {
printf("<%.*s>\n", (int) sz, extract);
} else {
printf("None\n");
}
}
int main() {
test("");
test("123");
test("\"123");
test("123\"");
test("\"123\"");
test("abc\"123");
test("abc\"123\"");
test("123\"xyz");
test("\"123\"xyz");
test("abc\"123\"xyz");
}
Expected output
<> --> None
<123> --> None
<"123> --> None
<123"> --> None
<"123"> --> <123>
<abc"123> --> None
<abc"123"> --> <123>
<123"xyz> --> None
<"123"xyz> --> <123>
<abc"123"xyz> --> <123>
I think that it is enough in the answer by unwind (even if you add code according to requirements)
A question similar to this question already exists.
Split unquoted string in C
When using that approach you can write follows:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ESCAPE '\\' //ESCAPE CHARACTER
typedef struct token {
const char *top;
const char *end;//point to next character
} Token;
Token getToken(const char **sp, char sep){
const char *s = *sp;
const char *top, *end;
Token token = { NULL, NULL};
while(*s && *s == sep)//skip top separators
++s;
if(!*s){
*sp = s;
return token;
}
token.top = s;
while(*s && *s != sep){
if(*s == ESCAPE)
++s;
else if(*s == '"'){
char *p = strchr(s + 1, '"');//search end '"'
while(p && p[-1] == ESCAPE)
p = strchr(p + 1, '"');
if(p)
s = p;
}
++s;
}
token.end = s;
*sp = s;
return token;
}
char *remove_escape(char *s){
char *from, *to;
from = to = s;
while(*from){
if(*from != ESCAPE)
*to++ = *from;
++from;
}
*to = 0;
return s;
}
char *ft_strsub(Token token){
size_t len = token.end - token.top;
char *sub = malloc(len + 1);//check return value
if (sub){
memcpy(sub, token.top, len);
sub[len] = 0;
}
return sub;
}
int main(int argc, char **argv){
char *str = NULL;
const char *s="haha \"lol\"";
Token token = getToken(&s, ' ');
while(token.top != NULL){
str = ft_strsub(token);
remove_escape(str);
if(*str == '"')//find it!
break;
free(str);
token = getToken(&s, ' ');
}
if(str){
printf("Found stuff inside quotes: ");
//remove "
size_t len = strlen(str);
str[len-1] = 0;
printf("'%s'\n", str + 1);//ignore first character or use memmove
free(str);
}
return 0;
}