根据初始格式解析字符串

时间:2011-11-20 01:00:32

标签: c string parsing

我正在尝试解析一组行并根据初始格式提取字符串的某些部分(读取配置文件)。

更多解释:格式最多可包含要格式化的 4 部分。这种情况,%S将跳过该部分,%a-%c将提取该部分,并将被视为字符串,%d为int。

我现在要做的是想出一些聪明的方法来解析它。到目前为止,我想出了以下原型。但是,我的指针算法仍然需要一些工作来跳过/提取部件。

最终每个部分都将存储在一个结构数组中。

使用sscanf

编辑在这种情况下可能不起作用,因为格式是在配置文件中指定的。此外,格式可能会缩放,字符串(和类型)可能会更改。

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

#define DIM(x) (sizeof(x)/sizeof(*(x)))

void process (const char *fmt, const char *line) {
   char c;
   const char *src = fmt;
   while ((c = *src++) != '\0')
   {   
      if (c == 'S');      // skip part
      else if (c == 'a'); // extract %a
      else if (c == 'b'); // extract %b
      else if (c == 'c'); // extract %c
      else if (c == 'd'); // extract %d (int)
      else { 
         printf("Unknown format\n");
         exit(1);
      }   
   }
}

static const char *input[] = {
   "bar 200.1 / / (zaz) - \"bon 10\"",
   "foo 100.1 / / (baz) - \"apt 20\"",
};

int main (void) {
   const char *fmt = "%S %a / / (%b) - \"%c %d\"";
   size_t i;
   for(i = 0; i < DIM (input); i++) 
   {
      process (fmt, input[i]);
   }   
   return (0);
}

2 个答案:

答案 0 :(得分:1)

scanf表达式有时足以分析实际输入,并且可以在运行时或编译时构建它们。因此,在尝试重新发明轮子之前,我会尝试遵循这条道路:

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

#define DIM(x) (sizeof(x)/sizeof(*(x)))

static const char *input[] = {
   "bar 200.1 / / (zaz) - \"bon 10\"",
   "foo 100.1 / / (baz) - \"apt 20\"",
};
const char *format = "%*[^ ] %[^ ] / / (%[^)]) - \" %[^ ] %d \"";

int main()
{
 typedef char buffer[100];
 buffer A,B,C;
 int D, i, p;

 for (i = 0; i < DIM(input); i++) {
  if ((p = sscanf(input[i], format, A, B, C, &D)) == 4)
   printf("%s %s %s %d\n", A, B, C, D);
  else
   printf("parsed only %d\n", p);
 }
}

产生

200.1 zaz bon 10
100.1 baz apt 20

答案 1 :(得分:0)

如果没有对每个占位符的严格定义,根据格式进行解析可能很困难。 您如何计划处理以下案件:

fmt = "(%c)";

input = "(a)bc)";

很明显,用户希望得到“a)bc”,但是因为')'是你的结束解析令牌,你才得到“a”