如何在没有正则表达式的情况下提取C中字符串中双引号之间的文本?

如何在没有正则表达式的情况下提取C中字符串中双引号之间的文本?,c,string,C,String,假设我的字符串是:haha“lol” 我只想提取lol #include<stdio.h> int main() { char a[20]={0}; char *s="haha \"lol\""; if(sscanf(s,"%*[^\"]'%[^\"]\"",a)==1){ printf("Found stuff inside quotes"); } } #包括 int main(){ 字符a[20]={0}; char*s=

假设我的字符串是:
haha“lol”

我只想提取
lol

#include<stdio.h>

int main() {  
   char a[20]={0};  
   char *s="haha \"lol\"";  
   if(sscanf(s,"%*[^\"]'%[^\"]\"",a)==1){  
      printf("Found stuff inside quotes");
   } 
}
#包括
int main(){
字符a[20]={0};
char*s=“哈哈”lol\”;
如果(s,“%*[^\”]'%[^\“]\”,a)=1){
printf(“在引号内找到内容”);
} 
}

为正在解析的源语言应用适当的解析器

用于解析输入的一行程序通常很脆弱,很难正确处理

也就是说,你可以试着用

const char *input = "haha \"lol\"";
char quoted[32];

if(sscanf(input, "%*[^\"]\"%31[^\"]\"", quoted) == 1)
{
  printf("got '%s'\n", quoted);
}

这应该被强化,但足以让您开始。

我认为答案中的这一点已经足够(即使您根据需求添加代码)

类似于此问题的问题已经存在。

使用该方法时,您可以编写以下内容:

#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;
}
#包括
#包括
#包括
#定义转义“\\”//转义字符
typedef结构令牌{
常量字符*顶部;
const char*end;//指向下一个字符
}代币;
令牌getToken(常量字符**sp,字符sep){
常量字符*s=*sp;
常量字符*顶部,*末端;
令牌={NULL,NULL};
while(*s&&*s==sep)//跳过顶部分隔符
++s;
如果(!*s){
*sp=s;
返回令牌;
}
token.top=s;
而(*s&&s!=sep){
如果(*s==转义)
++s;
如果(*s==“”),则为else{
char*p=strchr(s+1,“”);//搜索结束”
while(p&p[-1]==ESCAPE)
p=strchr(p+1,“”);
如果(p)
s=p;
}
++s;
}
token.end=s;
*sp=s;
返回令牌;
}
char*remove\u转义(char*s){
字符*从,*到;
从=到=s;
while(*from){
如果(*从!=转义)
*to++=*from;
++来自;
}
*to=0;
返回s;
}
char*ft_strsub(令牌){
size\u t len=token.end-token.top;
char*sub=malloc(len+1);//检查返回值
如有(附属){
memcpy(sub、token.top、len);
sub[len]=0;
}
返回子节点;
}
int main(int argc,字符**argv){
char*str=NULL;
const char*s=“哈哈大笑”;
Token-Token=getToken(&s',);
while(token.top!=NULL){
str=ft_strsub(令牌);
移除逃生通道(str);
如果(*str==“”)//找到它!
打破
自由基(str);
token=getToken(&s',);
}
如果(str){
printf(“在引号中找到内容:”);
//删除“
尺寸长度=strlen(str);
str[len-1]=0;
printf(“%s'\n”,str+1);//忽略第一个字符或使用memmove
自由基(str);
}
返回0;
}

有时一点代码就可以走很长的路。只需调用两次
strchr()

extract\u quoted\u string()
已更改为伪代码

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;
}
测试线束

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");
}
无效测试(常量字符*s){
printf(“-->”,s);
大小(四);;
const char*extract=extract_quoted_字符串(s和sz);
如果(摘录){
printf(“\n”,(int)sz,摘录);
}否则{
printf(“无”);
}
}
int main(){
测试(“”);
测试(“123”);
测试(“123”);
测试(“123\”);
测试(“123”);
测试(“abc\“123”);
测试(“abc\'123\”);
测试(“123\“xyz”);
测试(“123”xyz”);
测试(“abc\”123\“xyz”);
}
预期产量

<> --> 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>
-->无
-->没有
-->没有
--> 
-->没有
--> 
--> 

问题出在哪里?告诉我们你尝试了什么以及遇到了什么问题。我尝试过:#include int main(){char a[20]={0};char*s=“echo\'foobar\\\'”| cat;if(sscanf(s,“%*[^\”]'%[^\']\\”,a)==1){printf但是这不起作用,我不认为建议编写实际代码来迭代/解析字符串会被认为是有用的:(@chux这是一个很好的观点。我不会编辑以修复,因为这也是我的观点的一部分。:)使用
strchr()
可能会更好。谢谢!请问我在哪里可以了解更多关于sscanf和3号线的信息?@fredj0hnson:买一个好的。但为了快速参考,这本书很好。