字符串在C中搜索和格式化

时间:2012-07-19 23:43:34

标签: c string search buffer

快一点:在C中我有一个充满下面数据的缓冲区:

char buffer[255]="CODE=12345-MODE-12453-CODE1-12355"

我的问题是如何搜索这个。例如,对于CODE=12345,请注意数字会发生变化,因此我希望在CODE=*****部分之后使用通配符或预设数量的空格来搜索此CODE=

此方法不会编译最后一个尝试

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

int main ()
{
    char buf[255]="CODE=12345-MODE-12453-CODE1-12355";

#define TRIMSPACES(p) while(*p != '\0' && isspace((unsigned char)*p) != 0) ++p 
#define NSTRIP(p, n) p += n 
#define STRIP(p) ++p 

char* getcode(const char *input) 
{ 
  char *p = (char*) input, *buf, *pbuf; 

  if((buf = malloc(256)) == NULL) 
    return NULL; 

  pbuf = buf; 
  while(*p != '\0') { 
    if(strncmp(p, "CODE", 3) == 0) { 
      NSTRIP(p, 4); //remove 'code' 
      TRIMSPACES(p);//trim white-space after 'code' 

     if(*p != '=')  
       return NULL; 

      STRIP(p); // remove '=' 
      TRIMSPACES(p); //trim white-spaces after '=' 

/* copy the value until found a '-'  
   note: you must be control the size of it,  
   for avoid overflow. we allocated size, that's 256 
   or do subsequent calls to realloc() 
*/ 
      while(*p != '\0' && *p != '-') 
    *pbuf ++ = *p++; 

    //  break; 
    } 
    p ++; 
  } 

//put 0-terminator. 
  *pbuf ++ = '\0'; 

  return buf; 
} 




//   
}

4 个答案:

答案 0 :(得分:3)

您可以使用sscanf()函数:

int number;
sscanf(buffer, "CODE = %i", &number);

为了使其正常工作,您的缓冲区必须以空终止。

答案 1 :(得分:1)

假设CODE=部分始终位于字符串的开头,这很容易:

sscanf(buffer, "CODE = %d", &number);

...但您希望bufferchar[255],而不是unsigned long

编辑:如果CODE=部分不一定在字符串的开头,您可以使用strstr在缓冲区中查找CODE,从该点开始执行sscanf ,然后立即查看:

int codes[256];
char *pos = buffer;
size_t current = 0;

while ((pos=strstr(pos, "CODE")) != NULL) {
     if (sscanf(pos, "CODE = %d", codes+current))
         ++current;
     pos += 4;
}

EDIT2: 例如,你可以使用这样的东西:

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

int main ()
{
    // This is full of other junk as well 
    char buffer[255]="CODE=12345 MODE-12453 CODE=12355" ; 
    int i;
    int codes[256]; 
    char *pos = buffer; 
    size_t current = 0; 

    while ((pos=strstr(pos, "CODE")) != NULL) { 
        if (sscanf(pos, "CODE = %d", codes+current)) 
            ++current; 
        pos += 4; 
    } 

    for (i=0; i<current; i++)
        printf("%d\n", codes[i]);

    return 0;
}

对我来说,这会产生以下输出:

12345
12355

...正确读取两个“CODE = xxx”部分,但跳过“MODE = yyy”部分。

答案 2 :(得分:1)

另一种方法,而不是sscanf()

 char *input, *code;

  input = strstr(buf, "CODE");
  if(input == NULL) {
    printf("Not found CODE=\n");
    return -1;
  }

  code = strtok(strdup(input), "=");
  if(code != NULL) {
    code = strtok(NULL, "-");
    printf("%s\n", code); // code = atoi(code);
  } else {
    //not found '='
  }

或者更强大的方式......有点复杂:

    #define TRIMSPACES(p) while(*p != '\0' && isspace((unsigned char)*p) != 0) ++p
    #define NSTRIP(p, n) p += n
    #define STRIP(p) ++p

    char* getcode(const char *input, size_t limit)
{
    char *p = (char*) input, *buf, *pbuf;
    size_t i = 0;

    while(*p != '\0') {
        if(strncmp(p, "CODE", 3) == 0) {

        NSTRIP(p, 4); //remove 'code'
        TRIMSPACES(p);//trim all white-spaces after 'code'

        /* check we have a '=' after CODE (without spaces).
           if there is not, returns NULL
        */
        if(*p != '=') 
            return NULL;

        /* ok. We have.. now we don't need of it
            just remove it from we output string.
        */
        STRIP(p);

        /* remove again all white-spaces after '=' */
        TRIMSPACES(p);

        /* the rest of string is not valid,
            because are white-spaces values.
        */
        if(*p == '\0')
            return NULL;

        /* allocate space for store the value
            between code= and -.
            this limit is set into second parameter.
        */
        if((buf = malloc(limit)) == NULL)
            return NULL;

    /* copy the value until found a '-' 
        note: you must be control the size of it, 
       for don't overflow. we allocated 256 bytes.
        if the string is greater it, do implementation with
        subjecents call to realloc()
    */
     pbuf = buf;
      while(*p != '\0' && *p != '-' && i < limit) {
        *pbuf ++ = *p++; 
        i ++;
    }

      *pbuf ++ = '\0';
      return buf;
    }
    p ++;
  }

  return NULL;
}

然后:

char buf[255] = "foo baa CODE =     12345-MODE-12453-CODE-12355";
char *code = getcode(buf,256);

if(code != NULL) {
    printf("code = %s\n", code);
    free(code);
} else {
    printf("Not found code.\n");
}

输出:

  

代码= 12345

查看此online

如果你不想区分大小写,你可以使用那个POSIX函数的strncasecmp()

答案 3 :(得分:0)

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

char *getcode(const char *str, const char *pattern){
    //pattern: char is match, space is skip, * is collect
    static const char *p=NULL;
    char *retbuf, *pat;
    int i, match, skip, patlen;
    if(str != NULL) p=str;
    if(p==NULL || *p=='\0') return NULL;
    if(NULL==(retbuf=(char*)malloc((strlen(p)+1)*sizeof(char))))
        return NULL;
    pat = (char*)pattern;
    patlen = strlen(pat);
    i = match = skip = 0;
    while(*p){
        if(isspace(*p)){
            ++p;
            ++skip;
            continue;
        }
        if(*pat){
            if(*p == *pat){
                ++match;
                ++p;
                ++pat;
            } else if(*pat == '*'){
                ++match;
                retbuf[i++]=*p++;
                ++pat;
            } else {
                if(match){//reset
                    pat=(char*)pattern;
                    p -= match + skip -1;
                    i = match = skip = 0;
                } else //next
                    ++p;
            }
        } else {
            break;
        }
    }
    if(i){//has match
        retbuf[i++]='\0';
        retbuf=realloc(retbuf, i);
        return retbuf;
    } else {
        free(retbuf);
        return NULL;
    }
}

int main (){
    char *code;
    code=getcode("CODE=12345-MODE-12453-CODE1-12355", "CODE=*****");
    printf("\"%s\"\n",code);//"12345"
    free(code);
    code=getcode(" CODE = 12345-MODE-12453-CODE1-12355", "CODE=*****");
    printf("\"%s\"\n",code);//"12345"
    free(code);
    code=getcode("CODE-12345-MODE-12453-CODE1-12355", "CODE=*****");
    if(code==NULL)printf("not match\n");//not match
    code=getcode("CODE=12345-MODE-12453-CODE=12355", "CODE=*****");
    printf("\"%s\"\n",code);//"12345"
    free(code);
    code=getcode(NULL, "CODE=*****");
    printf("\"%s\"\n",code);//"12355"
    free(code);
    code=getcode("CODE=12345-MODE-12453-CODE1-12355", "CODE=*****");
    printf("\"%s\"\n",code);//"12345"
    free(code);
    code=getcode(NULL, "CODE1-*****");
    printf("\"%s\"\n",code);//"12355"
    free(code);
    return 0;
}