免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2278 | 回复: 8
打印 上一主题 下一主题

字符串分析, 交流一段代码 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 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:这是我在写一个分析文件的函数, 类似于分析配置文件。读一行, 分析一行。

谢谢, 欢迎交流。

论坛徽章:
0
2 [报告]
发表于 2010-05-09 17:09 |只看该作者
分析配置 文件

我建议你用bison(lex)/yacc
这个非常的不错

论坛徽章:
0
3 [报告]
发表于 2010-05-09 18:12 |只看该作者
这个问题需要看具体的应用。如果需求比较固定,楼主的方法是可行的。当然还能进一步限制语法,比如上面要求写成,每行一个等式的方式:
aaa=55
bbb=0.8
ccc=14
这样做起来简单。而且可以更加限制一下语法,让它变成:
i aaa=55
d bbb=0.8
i ccc=14
先读出每行的开头一个字母,然后直接利用sscanf之类的函数直接进行分析。

如果语法复杂,那么可以考虑二楼说的那些工具。或者自己学习一下编译原理词法语法之类相关内容。

论坛徽章:
0
4 [报告]
发表于 2010-05-09 20:18 |只看该作者
  1. sscanf(str,"aaa=%d   bbb=%lf ccc=%d", &a, &b, &c);
复制代码

论坛徽章:
0
5 [报告]
发表于 2010-05-09 22:57 |只看该作者
语法及词法分析器有点杀鸡用牛刀的味道了,而且多了一个预处理环节不大方便。这种小问题用正规式解决足矣。楼主#include <regex.h>然后再man regex.h慢慢学习吧。

论坛徽章:
0
6 [报告]
发表于 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 参数并取相应数据, 写代码时发现自己实习方法很笨, 遂发贴交流。

谢谢各位。

论坛徽章:
1
天秤座
日期:2014-04-27 07:42:20
7 [报告]
发表于 2010-05-10 11:26 |只看该作者
如果是文字分析,显然需要一个分析函数来处理这种问题,但你不要指望能有非常高的效率和正确率。如果是数据传输协议,那么事先约定就好,传的时候不要搞错内容,接收后自然不会解析出错误的数据来

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
8 [报告]
发表于 2010-05-10 14:57 |只看该作者
StringSplit就行了哈

论坛徽章:
0
9 [报告]
发表于 2010-05-10 15:50 |只看该作者
pcre亦可
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP