如何用C代码高效地读取固定格式的文本文件?

woshihuzi 2007-03-04 01:16:24
姓名 年龄 电子信箱 语文 数学
张三 15 zhangsan@1.net 95.5 67.3 // 这是注释
李四 12 lisi@2.net 36.2 99.9 /* 这样的注释也行
王五 23 wangwu@3.net 70 98 */
……

其中,空白部分是空格或者Tab键,注释的部分不作为数据读出。
显然,每一行数据是一条记录。我就定义一个结构体数组,数组的每一个元素用来存放一个记录。

如果没有C格式或者C++格式的注释,我自己会写程序读出来这些数据。问题是,在允许数据文件中出现上述两种注释的情况下,如何高效地读取这一行一行的数据到结构体数组当中去呢?请高手赐教。
...全文
622 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
why87485681155 2010-12-17
  • 打赏
  • 举报
回复
yaofem
woshihuzi 2007-03-06
  • 打赏
  • 举报
回复
最后的一点疑问,高手请指点一下嘛!
woshihuzi 2007-03-06
  • 打赏
  • 举报
回复
好!谢谢所有关注此问题的高手。
fosjos 2007-03-06
  • 打赏
  • 举报
回复
这种情况下还是用strtok好些
woshihuzi 2007-03-06
  • 打赏
  • 举报
回复
我的意思是当没有注释的时候,也不知道一行有多少个连续字符串(相互间以空白符号隔开),这种情况下,还能够使用sscanf来取出这一个个的连续字符串么?
fosjos 2007-03-06
  • 打赏
  • 举报
回复
sscanf的返回值是实际得到符合类型的参数个数,如果个数不符合就是格式错误
harold2007 2007-03-06
  • 打赏
  • 举报
回复
jf
闪人~
woshihuzi 2007-03-06
  • 打赏
  • 举报
回复
谢谢。如果没有注释,但是不能确保里面格式没有错,那该怎么读?是不是sscanf就不能用了?
qhgary 2007-03-06
  • 打赏
  • 举报
回复
如果没有注释,同时确保里面格式没有错的可能,同时也不会增加额外的需求的前提下可以考虑用sscanf或者getline,实际上底层还是逐字读的阿,只不过读到\n就返回给你而已,我觉得从效率上来说不会有明显得区别.
mLee79 2007-03-05
  • 打赏
  • 举报
回复
懒人总是用lex
woshihuzi 2007-03-05
  • 打赏
  • 举报
回复
不知道C/C++的编译器是怎么处理注视的,哪位大虾能指点一下?
woshihuzi 2007-03-05
  • 打赏
  • 举报
回复
基本明白了。谢谢楼上的各位!

还有一点疑问,请赐教:
1、在没有注释而且每行的列数固定的情况下,用sscanf效率高,还是逐字符读取效率高?
2、在没有注释而且每行的列数不固定的情况下,用sscanf还能奏效么?如果能,该怎么写代码?

qhgary 2007-03-05
  • 打赏
  • 举报
回复
C/C++编译器处理代码的时候是需要经过很多部骤的,就是说要扫描代码好几次才能进行编译处理的.你也可以这么做,首先把里面的注释去掉.怎么去呢?利用状态机一个个字符的读,当进入到//状态的时候就丢弃该行后面的内容,读到/*的时候就丢弃后面的字符直到读取到*/为止.你要反复处理几次,直到没有注释了为止.然后再getline逐行处理.
woshihuzi 2007-03-05
  • 打赏
  • 举报
回复
请问lex是什么呀?
lei001 2007-03-04
  • 打赏
  • 举报
回复
有点麻烦,只能边读取(一行一行的读取),边处理注释,
fosjos 2007-03-04
  • 打赏
  • 举报
回复
应该是先读到的优先
读到//直接赋'\0'
读到/*作个标记,一行一行寻找*/,如果在一行内,就用后面的覆盖这段,
不在一行的就一个换成'\0',另一个指针偏移
再用sscanf
总之,讨论一下就能解决
用正则不能一次解决,效率反而低了
believefym 2007-03-04
  • 打赏
  • 举报
回复
这个东东貌似很烦啊
/* //
// /*
//

存在的情况太多,/* 和//的优先级还不一定
woshihuzi 2007-03-04
  • 打赏
  • 举报
回复
to fosjos(无聊的菜鸟程序员)
-----------------------------------------------------
有没有这种情况:
张三 12 /* zs@1.net
*/ zs@2.com 36.2 99.9
李四 12 lisi@2.net 36.2 99.9
-----------------------------------------------------
没有,忽略掉注释部分之后,应该是很标准的一行一条记录


to277894613(秒大刀) :
-----------------------------------------------------
试试采用词法分析的方法
-----------------------------------------------------
偶编译原理学得不好,请问词法分析来解决这个问题的思路是什么?

-----------------------------------------------------
对了,你可以尝试使用正则表达式提取...
-----------------------------------------------------
C语言中能用证则表达式么?偶的系统是Win系统不是Linux系统。
fosjos 2007-03-04
  • 打赏
  • 举报
回复
有没有这种情况:
张三 12 /* zs@1.net
*/ zs@2.com 36.2 99.9
李四 12 lisi@2.net 36.2 99.9

fgets后,可以先把注释的删了,处理成标准格式,再用sscanf
分几种情况讨论,不是很难,有些麻烦而已
277894613 2007-03-04
  • 打赏
  • 举报
回复
对了,你可以尝试使用正则表达式提取...
加载更多回复(4)

69,371

社区成员

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

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