免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 24652 | 回复: 25

[C] C语言如何读取txt文档的最后一行数据 [复制链接]

论坛徽章:
0
发表于 2012-12-29 12:28 |显示全部楼层
本帖最后由 qw8990032 于 2012-12-29 12:30 编辑

C语言如何读取txt文档的最后一行数据,本人是新手,temp.txt文档的数据如下:
Device:0x796F Temp:13.6 C
Device:0x796F Temp:14.7 C
Device:0x796F Temp:14.7 C
Device:0x796F Temp:14.8 C
Device:0x796F Temp:14.9 C
Device:0x796F Temp:15.4 C
Device:0x796F Temp:14.7 C
Device:0x796F Temp:13.6 C
我只要求用C语言读取最后一行,然后打印出来,最好能给出整个程序供我参考一下,非常谢谢!

论坛徽章:
3
巳蛇
日期:2013-10-03 10:41:48申猴
日期:2014-07-29 16:12:04天蝎座
日期:2014-08-21 09:24:52
发表于 2012-12-29 12:36 |显示全部楼层
我能想到的是先移动到文件尾..
申请个字符串数组,再向前移动数组长度个位置,读进来,逆着找第一个\n.
大家有什么好办法吗..

论坛徽章:
0
发表于 2012-12-29 12:43 |显示全部楼层
第一个想到的办法和2楼一样

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
发表于 2012-12-29 12:52 |显示全部楼层
pandaiam 发表于 2012-12-29 12:36
大家有什么好办法吗

没有了^_^

论坛徽章:
0
发表于 2012-12-29 13:02 |显示全部楼层
回复 2# pandaiam


    哥们能不能给个程序?我也是这么想的,我学C语言不久,所以对文件操作这块不了解 ,谢谢

论坛徽章:
291
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
发表于 2012-12-29 14:55 |显示全部楼层
每行固定长度?那从文件末尾倒着seek行长,再读就是了

论坛徽章:
3
巳蛇
日期:2013-10-03 10:41:48申猴
日期:2014-07-29 16:12:04天蝎座
日期:2014-08-21 09:24:52
发表于 2012-12-29 15:14 |显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>


  5. int main(int argc, char** argv)
  6. {
  7.         FILE *fp;
  8.         char sline[1024];
  9.         size_t rd;
  10.         int i;
  11.        
  12.        
  13.         fp=fopen(argv[1], "r");
  14.         if(fp == NULL) {
  15.                 printf("%d,[%s]\n", errno, strerror(errno));
  16.                 return 0;
  17.         }
  18.        
  19.         fseek(fp, 0, SEEK_END);
  20.         if(ftell(fp) > 1023)
  21.                 fseek(fp, -1023, SEEK_CUR);
  22.         else
  23.                 fseek(fp, -ftell(fp), SEEK_CUR);
  24.        
  25.         memset(sline, 0, sizeof(sline));
  26.         rd=fread(sline, 1, 1023, fp);
  27.         if(sline[rd-1] == '\n')
  28.                 sline[rd-1] = 0;
  29.        
  30.         for(i=(1023>rd? rd:1023); i>=0; i--) {
  31.                 if(sline[i] == '\n') {
  32.                         break;
  33.                 }
  34.         }
  35.         if(i<0) {
  36.                 printf("this line is too long....\n");
  37.                 return 0;
  38.         }
  39.         printf("last line is:\n%s\n", sline+i+1);
  40.         return 0;
  41. }
  42. /* check for the last line */
复制代码
简单写的..
如果最后一行长度太大的话还得新申请内存把结果保存起来,等等..
  1. ./a.out rlf.c
  2. last line is:
  3. /* check for the last line */
复制代码

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
发表于 2012-12-29 15:32 |显示全部楼层
这种虽然需求小,但边界复杂,不容易写好,很容易就藏bug
我试着写了一下,没做什么测试,所以肯定会有bug。
在gcc4.7.2(-std=c99)编译通过
  1. #include <stdio.h>
  2. #include <string.h>

  3. // 获取二进制方式打开的文本文件file中pos位置之前的c字符所在位置加1
  4. fpos_t getlastlinepos( FILE* file, fpos_t pos, char c )
  5. {
  6.     char buf[256+1]; // 没有memrchr这种函数,而strrchr要求字符串以零结尾,所以+1;buf的长度随便设,只是个暂时的缓存
  7.     const size_t buflen = sizeof(buf)/sizeof(buf[0]) - 1;
  8.      for( fpos_t fpos=pos; fpos!=0; )
  9.     {
  10.         size_t n = fpos>=buflen ? buflen : (size_t)fpos;
  11.         fpos = fpos-n;
  12.         fsetpos( file, &fpos );
  13.         buf[ fread(buf,1,n,file) ] = '\0';

  14.         const char* p = strrchr( buf, c );
  15.         if( p )
  16.             return fpos+(p-buf)+1;
  17.     }

  18.     return 0;
  19. }

  20. // 输出二进制方式打开的文本文件file中[pos1,pos2)位置之间的字符串
  21. void printfilecontent( FILE* file, fpos_t pos1, fpos_t pos2 )
  22. {
  23.     fsetpos( file, &pos1 );
  24.     char buf[256]; // buf的长度随便设,只是个暂时的缓存
  25.     const size_t buflen = sizeof(buf)/sizeof(buf[0]);
  26.     for( fpos_t pos=pos1; pos<pos2; pos+=(pos+buflen<pos2?buflen:pos2-pos) )
  27.     {
  28.         size_t n = fread( buf, 1, pos+buflen<pos2?buflen:(size_t)(pos2-pos), file );
  29.         printf( "%.*s", n-(buf[n-1]=='\r'), buf );
  30.     }
  31. }

  32. int main()
  33. {
  34.     FILE* file = fopen( "temp.txt", "rb" ); // 若会移动文件指针,俺喜欢用二进制方式,不但速度快,而且能避开一些库函数的bug
  35.     if( !file )
  36.         return 1;
  37.     fseek( file, 0, SEEK_END );
  38.     fpos_t flen;
  39.     fgetpos( file, &flen ); // 获得了文件长度,存于 flen 中
  40.    
  41.     printf( "倒数第一行是: " );
  42.     fpos_t pos1 = getlastlinepos( file, flen, '\n' );
  43.     printfilecontent( file, pos1, flen );
  44.     printf( "\n" );

  45.     if( pos1 > 1 )
  46.     {
  47.         printf( "倒数第二行是: " );
  48.         fpos_t pos2 = getlastlinepos( file, pos1-1, '\n' );
  49.         printfilecontent( file, pos2, pos1-1 );
  50.         printf( "\n" );
  51.     }

  52.     fclose( file );
  53.     return 0;
  54. }
复制代码

论坛徽章:
0
发表于 2012-12-29 18:12 |显示全部楼层
回复 8# bruceteen
有很多次错误:
4.c: 在函数 ‘getlastlinepos’ 中:
4.c:9: 错误:在 C99 模式之外使用 ‘for’ 循环初始化声明
4.c:9: 错误:双目运算符 != 操作数无效
4.c:11: 错误:双目运算符 >= 操作数无效
4.c:11: 错误:需要整数时使用了聚合值
4.c:12: 错误:双目运算符 - 操作数无效
4.c:18: 错误:双目运算符 + 操作数无效
4.c:21: 错误:返回时类型不兼容
4.c: 在函数 ‘printfilecontent’ 中:
4.c:30: 错误:在 C99 模式之外使用 ‘for’ 循环初始化声明
4.c:30: 错误:双目运算符 < 操作数无效
4.c:30: 错误:双目运算符 + 操作数无效
4.c:30: 错误:双目运算符 - 操作数无效
4.c:32: 错误:双目运算符 + 操作数无效
4.c:32: 错误:双目运算符 - 操作数无效
4.c: 在函数 ‘main’ 中:
4.c:51: 错误:双目运算符 > 操作数无效
4.c:54: 错误:双目运算符 - 操作数无效
4.c:55: 错误:双目运算符 - 操作数无效
4.c:61:2: 警告:文件未以空白行结束


   

论坛徽章:
0
发表于 2012-12-29 18:20 |显示全部楼层
回复 7# pandaiam
非常谢谢!!

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会

【架构革新 高效可控】2020年12月21日-23日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP