如何从C中的字符串中提取子字符串?

时间:2013-10-24 01:44:16

标签: c string c-strings

我尝试过使用strncmp,但只有在我给它提取一个特定数量的字节时它才有用。

char line[256] = This "is" an example. //I want to extract "is"
char line[256] = This is "also" an example. // I want to extract "also"
char line[256] = This is the final "example".  // I want to extract "example"
char substring[256]

我如何提取“”之间的所有元素?并将其放在变量substring?

5 个答案:

答案 0 :(得分:7)

注意:在我意识到编写代码会导致问题后我编辑了这个答案,因为strtok不喜欢对const char*变量进行操作。这更像是我编写示例的工件,而不是基本原理的问题 - 但显然它应该是双重downvote。所以我修好了。

以下工作(使用gcc在Mac OS 10.7上测试):

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

int main(void) {
const char* lineConst = "This \"is\" an example"; // the "input string"
char line[256];  // where we will put a copy of the input
char *subString; // the "result"

strcpy(line, lineConst);

subString = strtok(line,"\""); // find the first double quote
subString=strtok(NULL,"\"");   // find the second double quote

printf("the thing in between quotes is '%s'\n", subString);
}

以下是它的工作原理:strtok查找“分隔符”(第二个参数) - 在本例中是第一个"。在内部,它知道“它到底有多远”,如果再次使用NULL作为第一个参数(而不是char*)再次调用它,它将从那里再次启动。因此,在第二次调用时,它返回“恰好是第一个和第二个双引号之间的字符串”。这就是你想要的。

警告: strtok通常会使用'\0'替换分隔符,因为它会“输入”输入。因此,您必须依靠此方法修改输入字符串。如果这是不可接受的,您必须先制作本地副本。本质上,当我将字符串常量复制到变量时,我在上面这样做。通过调用line=malloc(strlen(lineConst)+1);free(line);之后执行此操作会更简洁 - 但如果您打算将其包装在函数内,则必须考虑返回值必须在函数后保持有效返回...因为strtok返回指向字符串内正确位置的指针,所以它不会复制该令牌。将指针传递到您希望结果结束的空间,并在函数内创建该空间(具有正确的大小),然后将结果复制到其中,这是正确的做法。这一切都非常微妙。如果不清楚,请告诉我!

答案 1 :(得分:0)

这是一个很长的方法:假设要提取的字符串将使用引号 (修正了以下评论中kieth建议的错误检查)

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

int main(){

    char input[100];
    char extract[100];
    int i=0,j=0,k=0,endFlag=0;

    printf("Input string: ");
    fgets(input,sizeof(input),stdin);
    input[strlen(input)-1] = '\0';

    for(i=0;i<strlen(input);i++){
        if(input[i] == '"'){

                j =i+1;
                while(input[j]!='"'){
                     if(input[j] == '\0'){
                         endFlag++;
                         break;
                     }
                     extract[k] = input[j];
                     k++;
                     j++;
                }
        }
    }
    extract[k] = '\0';

    if(endFlag==1){
        printf("1.Your code only had one quotation mark.\n");
        printf("2.So the code extracted everything after that quotation mark\n");
        printf("3.To make sure buffer overflow doesn't happen in this case:\n");
        printf("4.Modify the extract buffer size to be the same as input buffer size\n");

        printf("\nextracted string: %s\n",extract);
    }else{ 
       printf("Extract = %s\n",extract);
    }

    return 0;
}

<强>输出(1):

$ ./test
Input string: extract "this" from this string
Extract = this

<强>输出(2):

$ ./test
Input string: Another example to extract "this gibberish" from this string
Extract = this gibberish

输出(3):( Kieth建议的错误检查)

$ ./test

Input string: are you "happy now Kieth ?
1.Your code only had one quotation mark.
2.So the code extracted everything after that quotation mark
3.To make sure buffer overflow doesn't happen in this case:
4.Modify the extract buffer size to be the same as input buffer size

extracted string: happy now Kieth ?

<强> -------------------------------------------- -------------------------------------------------- ----------------------------------

虽然没有要求它 - 以下代码从输入字符串中提取多个单词,只要它们在引号中:

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

int main(){

    char input[100];
    char extract[50];
    int i=0,j=0,k=0,endFlag=0;

    printf("Input string: ");
    fgets(input,sizeof(input),stdin);
    input[strlen(input)-1] = '\0';

    for(i=0;i<strlen(input);i++){
        if(input[i] == '"'){
            if(endFlag==0){
                j =i+1;
                while(input[j]!='"'){
                     extract[k] = input[j];
                     k++;
                     j++;
                }
                endFlag = 1;
            }else{
               endFlag =0;
            }

            //break;
        }
    }

    extract[k] = '\0';

    printf("Extract = %s\n",extract);

    return 0;
}

<强>输出:

$ ./test
Input string: extract "multiple" words "from" this "string"
Extract = multiplefromstring

答案 2 :(得分:0)

您是否尝试过查看strchr功能?您应该能够调用该函数两次以获取指向"字符的第一个和第二个实例的指针,并使用memcpy和指针算法的组合来获得您想要的内容。

答案 3 :(得分:0)

如果你想在没有库支持的情况下这样做......

void extract_between_quotes(char* s, char* dest)
{
   int in_quotes = 0;
   *dest = 0;
   while(*s != 0)
   {
      if(in_quotes)
      {
         if(*s == '"') return;
         dest[0]=*s;
         dest[1]=0;
         dest++;
      }
      else if(*s == '"') in_quotes=1;
      s++;
   }
}

然后调用它

  

extract_between_quotes(line, substring);

答案 4 :(得分:0)

#include <string.h>
...        
substring[0] = '\0';
const char *start = strchr(line, '"') + 1;
strncat(substring, start, strcspn(start, "\""));

省略了边界和错误检查。避免strtok,因为它有副作用。