忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12下一页
最近访问板块 发新帖
查看: 3954 | 回复: 19

[C] 求日志文件最后的行输出 [复制链接]

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-07-18 06:20:00
发表于 2013-05-04 00:27 |显示全部楼层
本帖最后由 lyl2002 于 2013-05-04 00:41 编辑

有一个日志文件,有n行,我现在要printf这个日志文件最后m行,而且需要按第1个字段顺序打印,把n>=m或m>n的情况都考虑进去,用纯C如何实现

日志文件内容:
101|101001|101236|0000|
102|101001|101236|0000|
103|101001|101236|0000|
.....
.....
.....
n-2|101001|101236|0000|
n-1|101001|101236|0000|
n|101001|101236|0000|




如果m=3,最后输出结果是
n-2|101001|101236|0000|
n-1|101001|101236|0000|
n|101001|101236|0000|

论坛徽章:
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
发表于 2013-05-04 09:26 |显示全部楼层
就是做个循环数组,有空余时插入到空余处,无空余时替换到最先进入的数据

以下代码在gcc4.72(加编译参数-std=c99)上编译通过,但没测试过,你自己参考一下
  1. #include <stdio.h>

  2. #define LINELEN 50

  3. int main()
  4. {
  5.     FILE *fin = fopen( "lyl2002.txt", "rt" );
  6.     if( !fin )
  7.         return 1;

  8.     const size_t m = 3;
  9.     char rls[m][LINELEN];
  10.     size_t rlsnum = 0;
  11.     size_t rlsptr = 0;
  12.     for( ; fgets(rls[rlsptr],LINELEN*sizeof(char),fin); rlsptr=(rlsptr+1)%m, rlsnum<m?++rlsnum:0 );

  13.     fclose( fin );

  14.     ///

  15.     for( size_t i=rlsptr-rlsnum; i!=rlsptr; ++i )
  16.         printf( "%s", rls[(i+m)%m] );

  17.     return 0;
  18. }
复制代码

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-07-18 06:20:00
发表于 2013-05-04 09:51 |显示全部楼层
2楼的确很高深,能不能写的再通俗一点

论坛徽章:
257
射手座
日期: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
发表于 2013-05-04 10:03 |显示全部楼层
参考 tail  

论坛徽章:
257
射手座
日期: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
发表于 2013-05-04 10:07 |显示全部楼层
n很大并且远远大于m时最好倒着读

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-07-18 06:20:00
发表于 2013-05-04 10:11 |显示全部楼层
本帖最后由 lyl2002 于 2013-05-04 10:12 编辑

一定要倒着读,我这个日志文件很大的,每天都有很大的交易量,有没有倒着读的方法参考啊

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2013-05-04 10:40 |显示全部楼层
本帖最后由 linux_c_py_php 于 2013-05-04 10:44 编辑
lyl2002 发表于 2013-05-04 09:51
2楼的确很高深,能不能写的再通俗一点


循环数组, 一个记录front, 一个记录队列长度, 每3个就长度清零, 最后用front减去队列长度得到rear,然后打印从rear到front的数据,因为是循环队列所以(rear + m) % m保证是数组内下标.


论坛徽章:
0
发表于 2013-05-04 10:49 |显示全部楼层
本帖最后由 hbmhalley 于 2013-05-04 10:55 编辑

倒着读的
  1. #include <stdio.h>

  2. int main (int argc , char *argv[]) {
  3.         FILE *fp ;
  4.         int m ;

  5.         if (argc != 3
  6.                         || (fp = fopen (argv[1] , "r")) == NULL
  7.                         || sscanf (argv[2] , "%d" , &m) != 1
  8.                         || m <= 0) {
  9.                 fputs ("arg error\n" , stderr) ;
  10.                 return 1 ;
  11.         }

  12.         long st ;
  13.         int cnt = m ;
  14.         fseek (fp , 0 , SEEK_END) ;
  15.         for (st = 1 ; ftell (fp) != 0 ; st <<= 1) {
  16.                 if (fseek (fp , -st , SEEK_CUR) != 0) {
  17.                         st = ftell (fp) ;
  18.                         fseek (fp , 0 , SEEK_SET) ;
  19.                 }

  20.                 long i ;
  21.                 for (i = 0 ; i < st ; ++i)
  22.                         cnt -= fgetc (fp) == '\n' ;

  23.                 fseek (fp , -st , SEEK_CUR) ;
  24.                 if (cnt < 0)
  25.                         break ;
  26.         }

  27.         while (cnt < 0)
  28.                 cnt += fgetc (fp) == '\n' ;

  29.         int c ;
  30.         while ((c = fgetc (fp)) != EOF)
  31.                 putchar (c) ;

  32.         return 0 ;
  33. }
复制代码

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2013-05-04 10:54 |显示全部楼层
lyl2002 发表于 2013-05-04 10:11
一定要倒着读,我这个日志文件很大的,每天都有很大的交易量,有没有倒着读的方法参考啊


实现tail的功能, 包括tail -f的功能, 就是从末尾往前找换行