C代码如何高效读取格式化的文本?

woshihuzi 2014-10-17 04:25:17
有下面的文本,假定有几十行

f(abc,甲)=丙
f(a,乙)=戊
f(48,丙)=戊
f(阿3,丁)=乙

这是有规律的,框架就是:
f (*,*)=*

我需要把一行中这三个*代表的内容找出来,存到三个字符缓冲区中去。

我自己写的代码特别啰嗦,我知道正则表达式能简单地处理这个问题,但C语言引入正则表达式我不会。所以:

请问除了引入正则表达式处理机制外有没有高效的办法?
...全文
614 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_22134911 2014-10-18
  • 打赏
  • 举报
回复
赵哥先fgets了一下,肯定会丢掉一行。 可以fgets+sscanf,其他都可以参考赵哥代码。
Zephyr风暴之锤 2014-10-18
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
//in.txt:
//f(abc,甲)=丙
//f(a,乙)=戊
//f(48,丙)=戊
//f(阿3,丁)=乙
//
//这是有规律的,框架就是:
//f (*,*)=*
#include <stdio.h>
FILE *f;
char ln[80];
char s1[40];
char s2[40];
char s3[40];
int i;
int main() {
    f=fopen("in.txt","r");
    if (NULL==f) {
        printf("Can not open file in.txt!\n");
        return 1;
    }
    i=0;
    while (1) {
        if (NULL==fgets(ln,80,f)) break;
        if (3==fscanf(f,"f(%39[^,],%39[^)])=%39[^\n]",s1,s2,s3)) {
            printf("[%s],[%s],[%s]\n",s1,s2,s3);
        } else {
            printf("in.txt line %d format error:%s",i+1,ln);
        }
        i++;
    }
    fclose(f);
    return 0;
}
//[abc],[甲],[丙]
//[a],[乙],[戊]
//[48],[丙],[戊]
//[阿3],[丁],[乙]
//
好赞好赞!!!
woshihuzi 2014-10-18
  • 打赏
  • 举报
回复
看来得专题专问,我提的额外问题到其它地方文问去吧。此贴问题解决,结贴,谢谢赵哥和其他高手。
赵4老师 2014-10-18
  • 打赏
  • 举报
回复
纠正第25行:
if (3==fscanf(f,"f(%39[^,],%39[^)])=%39[^\n]",s1,s2,s3)) {
应为
if (3==sscanf(ln,"f(%39[^,],%39[^)])=%39[^\n]",s1,s2,s3)) {
woshihuzi 2014-10-18
  • 打赏
  • 举报
回复
现在明白了,高手真多啊。我以前只知道%d、%c、%s啊之类的,都是读到字符缓冲区里面自己用*p++=*q++慢慢搞。 还有两个问题: 1、如果文件里面输入的行里面有空格,那我获取到的s1、s2、s3是有空格的,那么,去掉字符串首尾的空白有现成的函数吗?没有的话,如何写代码才能让这个处理效率高一些? 2、如果有些行后半部分跟着双斜线注释,那赵哥的代码应该如何改进才能得到s1、s2、s3?
Uron 2014-10-18
  • 打赏
  • 举报
回复
引用 4 楼 woshihuzi 的回复:
谢谢2楼的高手,代码确实简洁高效。 不过,输出结果中,原来的第一行数据显示不出来: [a],[乙],[戊] [48],[丙],[戊] [阿3],[丁],[乙] 另外,请解释一下fscanf(f,"f(%39[^,],%39[^)])=%39[^\n]",s1,s2,s3))的含义好吗?让俺也知其所以然。
f(到,之间的字符放入s1,最多放入39个字符,后面类似。 ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C: %[ABC] 使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。 用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。
woshihuzi 2014-10-18
  • 打赏
  • 举报
回复
谢谢2楼的高手,代码确实简洁高效。 不过,输出结果中,原来的第一行数据显示不出来: [a],[乙],[戊] [48],[丙],[戊] [阿3],[丁],[乙] 另外,请解释一下fscanf(f,"f(%39[^,],%39[^)])=%39[^\n]",s1,s2,s3))的含义好吗?让俺也知其所以然。
707wk 2014-10-17
  • 打赏
  • 举报
回复
看楼上代码。。。。
赵4老师 2014-10-17
  • 打赏
  • 举报
回复
//in.txt:
//f(abc,甲)=丙
//f(a,乙)=戊
//f(48,丙)=戊
//f(阿3,丁)=乙
//
//这是有规律的,框架就是:
//f (*,*)=*
#include <stdio.h>
FILE *f;
char ln[80];
char s1[40];
char s2[40];
char s3[40];
int i;
int main() {
    f=fopen("in.txt","r");
    if (NULL==f) {
        printf("Can not open file in.txt!\n");
        return 1;
    }
    i=0;
    while (1) {
        if (NULL==fgets(ln,80,f)) break;
        if (3==fscanf(f,"f(%39[^,],%39[^)])=%39[^\n]",s1,s2,s3)) {
            printf("[%s],[%s],[%s]\n",s1,s2,s3);
        } else {
            printf("in.txt line %d format error:%s",i+1,ln);
        }
        i++;
    }
    fclose(f);
    return 0;
}
//[abc],[甲],[丙]
//[a],[乙],[戊]
//[48],[丙],[戊]
//[阿3],[丁],[乙]
//
铖邑 2014-10-17
  • 打赏
  • 举报
回复
这种貌似用scanf就能搞定了

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧