使用替代终止字符执行strcmp的标准方法?

时间:2013-07-28 06:27:52

标签: c string parsing string-matching

所以我有一个像这样的字符串:

char* line="foo bar\tbaz\nbiz";

我想一次一个字地解析这个字符串,根据单词做不同的事情。像这样:

void process_word(const char* str) //str will point to the beginning of a word
{
  if(!strcmp(str, "foo")){
    foo();
  }else if(!strcmp(str, "bar")){
    bar();
  }else{
    others();
  }
}

我该如何做到这一点,以便我可以使用类似strcmp的东西,而不是在\ 0停止比较,而是停在空格或其他空格字符?

没有新缓冲区创建的补充点或正则表达式等过度杀伤解决方案

4 个答案:

答案 0 :(得分:0)

这只会检查模式,无论单词终止字符

int mystrncmp(const char *line, const char *pattern)
{
   int len = strlen(pattern);
   return strncmp(line,pattern,len);
}

答案 1 :(得分:0)

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

#define WHITE_SPACE " \t\n"

int strcmp2ws(const char *s1, const char *s2){
    size_t len1, len2;
    len1 = strcspn(s1, WHITE_SPACE);
    len2 = strcspn(s2, WHITE_SPACE);

    return strncmp(s1, s2, (len1 <= len2) ? len2 : len1);
}

int main(void){
    char* line="foo bar\tbaz\nbiz";
    //test
    if(!strcmp2ws(line, "foo"))
        printf("foo\n");
    if(!strcmp2ws(strchr(line, ' ') + 1, "bar"))
        printf("bar\n");
    if(!strcmp2ws(strchr(line, '\t') + 1, "baz"))
        printf("baz\n");
    if(!strcmp2ws(strchr(line, '\n') + 1, "biz"))
        printf("biz\n");
    return 0;
}

答案 2 :(得分:0)

函数strcspn给出一个字符串的长度,直到一组“拒绝”字符。将它与strncmp结合起来可以给你你想要的东西。

#include <string.h>

const char delimiters = " \t\n";

void process_word(const char* str, size_t len) //str will point to the beginning of a word
{
  if(!strncmp(str, "foo", len)){
    foo();
  }else if(!strncmp(str, "bar", len)){
    bar();
  }else{
    others();
  }
}

void parse(const char *s)
{
    size_t i, len;

    i = 0;
    while (s[i] != '\0') {
        len = strcspn(&s[i], delimiters);
        process_word(&s[i], len);
        i += len;
    }
}

答案 3 :(得分:0)

这是一个可能的解决方案:

const char* next_word_is(const char* haystack, const char* needle) {
  size_t len = strlen(needle);
  const char* end = &haystack[len];
  if (strncmp(haystack, needle, len) == 0 && (!*end || isspace(*end)))
    return end;
  return NULL;
}

如果使用字符串文字作为第二个参数调用它,它可能会被内联,并且strlen()调用将被消除。将end作为成功指标返回可能并不理想;根据您的需要,您可能希望转到下一个单词的开头。