Chinaunix

标题: 字符串分析, 交流一段代码 [打印本页]

作者: changyongID    时间: 2010-05-09 17:05
标题: 字符串分析, 交流一段代码
大家好。

比如有现在这样一串字符串

char *str = "aaa=55   bbb=0.8 ccc=14";
要分别读出其中aaa, bbb, ccc三个参数的值, 其中bbb为double型, aaa, ccc为int
三个参数间用空格隔开。

现在我写了一段代码, 可以来分析这行字符, 并正确读出各值 。
但是我觉得我的代码中用的方法太差了, 感觉用这种方法太死了。

我的代码如下
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. static int
  5. read_bookmark_line(const char *cp1, int *aaa, double *bbb, int *ccc)
  6. {
  7.         char *cp3;

  8.         cp3 = strchr(cp1, '=');
  9.         if (strncmp(cp1, "aaa", cp3 - cp1) == 0) {
  10.                 *aaa = atoi(++cp3);
  11.         }

  12.         cp1 = cp3++;
  13.         cp3 = strchr(cp1, '=');
  14.         while (*++cp1 != ' ');
  15.         while (*++cp1 == ' ');
  16.         if (strncmp(cp1, "bbb", cp3 - cp1) == 0) {
  17.                 *bbb = atof(++cp3);
  18.         }

  19.         cp1 = cp3++;
  20.         cp3 = strchr(cp1, '=');
  21.         while (*++cp1 != ' ');
  22.         while (*++cp1 == ' ');
  23.         if (strncmp(cp1, "ccc", cp3 - cp1) == 0) {
  24.                 *ccc = atoi(++cp3);
  25.         }

  26.         if (*aaa == 0)
  27.                 return 0;

  28.         return 1;
  29. }

  30. char *str = "aaa=55   bbb=0.8 ccc=14";

  31. int
  32. main(void)
  33. {
  34.         int aaa, ccc;
  35.         double bbb;

  36.         char *s = str;
  37.         read_bookmark_line(s, &aaa, &bbb, &ccc);

  38.         printf("aaa= %d, bbb = %f, ccc = %d\n",
  39.                 aaa, bbb, ccc);

  40.         return 0;
  41. }
复制代码
感觉其中的read_bookmark_line, 被我写的太烂了,没有丝毫的方法性可言。
不知道大家对这段代码怎么看?或是有什么意见。

PS:这是我在写一个分析文件的函数, 类似于分析配置文件。读一行, 分析一行。

谢谢, 欢迎交流。
作者: linuxlixk    时间: 2010-05-09 17:09
分析配置 文件

我建议你用bison(lex)/yacc
这个非常的不错
作者: xiexiecn    时间: 2010-05-09 18:12
这个问题需要看具体的应用。如果需求比较固定,楼主的方法是可行的。当然还能进一步限制语法,比如上面要求写成,每行一个等式的方式:
aaa=55
bbb=0.8
ccc=14
这样做起来简单。而且可以更加限制一下语法,让它变成:
i aaa=55
d bbb=0.8
i ccc=14
先读出每行的开头一个字母,然后直接利用sscanf之类的函数直接进行分析。

如果语法复杂,那么可以考虑二楼说的那些工具。或者自己学习一下编译原理词法语法之类相关内容。
作者: ubuntuer    时间: 2010-05-09 20:18
  1. sscanf(str,"aaa=%d   bbb=%lf ccc=%d", &a, &b, &c);
复制代码

作者: 没本    时间: 2010-05-09 22:57
语法及词法分析器有点杀鸡用牛刀的味道了,而且多了一个预处理环节不大方便。这种小问题用正规式解决足矣。楼主#include <regex.h>然后再man regex.h慢慢学习吧。
作者: changyongID    时间: 2010-05-10 00:03
谢谢楼上几位

发才用sscanf 来处理我的问题蛮方便的。只是这样的话, 文件中的内容就要事先约定好。 某些地方多一个空格都不行。

5#没本说的这个regex.h倒是从未听说过,长见识了。去看下。

其实分析配置文件有个dotconf蛮不错的。 只是我这里的各参数会写在一行。而不能分行写。例如下面这样的例子

....
<test>
aaa=3 bbb=5.4 ccc=2
aaa=3 bbb=5.4 ccc=2
aaa=3 bbb=5.4 ccc=2
aaa=3 bbb=5.4 ccc=2
</test>
....

所以在这个文件中我要先找到test匹配项, 再读<test> 和 </test>之间的数行, 每一行的内容都存于一个结构里, 一个匹配项下面会有数量不定的结构。
这就是我的需求。

大概实现方法已经想到(一个链表, 读一行后就向链表中插一个结构)


隔开aaa bbb ccc 参数并取相应数据, 写代码时发现自己实习方法很笨, 遂发贴交流。

谢谢各位。
作者: A.com    时间: 2010-05-10 11:26
如果是文字分析,显然需要一个分析函数来处理这种问题,但你不要指望能有非常高的效率和正确率。如果是数据传输协议,那么事先约定就好,传的时候不要搞错内容,接收后自然不会解析出错误的数据来
作者: egmkang    时间: 2010-05-10 14:57
StringSplit就行了哈
作者: huxk    时间: 2010-05-10 15:50
pcre亦可




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2