10

我尝试使用 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]

我将如何提取“”之间的所有元素?并将其放入变量子字符串中?

4

5 回答 5

15

注意:在我意识到编写代码会导致strtok不喜欢对const char*变量进行操作的问题后,我编辑了这个答案。这更像是我如何编写示例的人工制品,而不是基本原理的问题——但显然它值得双重反对。所以我修好了。

以下作品(使用 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作为第一个参数(而不是 a char*),它将从那里重新开始。因此,在第二次调用时,它返回“恰好是第一个和第二个双引号之间的字符串”。这就是你想要的。

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

于 2013-10-24T01:50:36.827 回答
2

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

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);

于 2013-10-24T01:58:37.600 回答
1

这是一个很长的路要走:假设要提取的字符串将用引号引起来 (修复了 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):(基思建议的错误检查)

$ ./测试

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
于 2013-10-24T01:50:29.580 回答
0
#include <string.h>
...        
substring[0] = '\0';
const char *start = strchr(line, '"') + 1;
strncat(substring, start, strcspn(start, "\""));

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

于 2013-10-24T12:30:17.047 回答
0

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

于 2013-10-24T01:50:31.453 回答