这里是我想读出的文件,里面有一些意想不到的'\0'
下面是我的代码,有两种方法将其读取到shell,一种是使用fgets(),另一种是使用Linux 'head' cmd;
这是两种方法的结果
一个是fgets
Mon Aug 28 14:29:29 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 1 ont-info
Mon Aug 28 14:29:33 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 1 ont-unbound
Mon Aug 28 14:29:41 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:43 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:44 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:47 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:51 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:53 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:31:18 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:33:50 2023 admin[::ffff:192.168.7.116]:59927: exi
Mon Aug 28 14:33:51 2023 admin[::ffff:192.168.7.116]:59927: exi
Mon Aug 28 14:33:54 2023 admin[::ffff:192.168.7.116]:59927: save config
Mon Aug 28 14:37:01 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:03 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:07 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:21 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:22 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:27 2023 admin[::ffff:192.168.7.116]:60207: show slot
一个头CMD
Mon Aug 28 14:29:29 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 1 ont-info
Mon Aug 28 14:29:33 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 1 ont-unbound
Mon Aug 28 14:29:41 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:43 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:44 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:47 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:51 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:29:53 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:31:18 2023 admin[::ffff:192.168.7.116]:59927: brief-show slot 2 ont-info
Mon Aug 28 14:33:50 2023 admin[::ffff:192.168.7.116]:59927: exi
Mon Aug 28 14:33:51 2023 admin[::ffff:192.168.7.116]:59927: exi
Mon Aug 28 14:33:54 2023 admin[::ffff:192.168.7.116]:59927: save config
Mon Aug 28 14:37:00 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:01 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:03 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:07 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:21 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:22 2023 admin[::ffff:192.168.7.116]:60207: show slot
Mon Aug 28 14:37:27 2023 admin[::ffff:192.168.7.116]:60207: show slot
你可以看到错误的行与时间“14:37:00”得到打印出来的头cmd,而与fgets没有;所以我很困惑头命令是如何打印出以'\0'开头的字符串的?
是head cmd擦除所有'\0',我试图将head cmd的输出推送到文件head -n 20 cli_log > head_log
中,但我打开head_log,发现它与log_log相同。
3条答案
按热度按时间txu3uszq1#
fgets
是一个string
文件函数,\0
在C字符串中有非常特殊的含义。这就是为什么它不像你认为的那样工作的原因。如果文件格式不正确,请不要对函数进行字符串处理。
您需要将此文件视为二进制文件并相应地读取它
yqhsw0fo2#
您的fgets-using程序使用
printf("%s", line);
行打印。由于\0
是C字符串中的字符串终止字符,以\0
开头的行在printf中看起来像是一个空字符串,因此它什么也不打印。但是,unixhead
命令可以处理文件中可能出现的所有字节,包括值为0的字节。li9yvcax3#
fgets()
可以读取 * 空字符 *,将其保存到缓冲区中并继续阅读。这不是直接的问题。问题是
printf("%s", line);
,因为打印在line
中的 * 第一个 * 空字符处停止,无论是fgets()
读入的空字符还是fgets()
在完成时附加的空字符。打印用
fwrite(line, 1, n, stdout)
读取的n
字符,而不是printf("%s", line);
。对于
fgets()
,查找n
读取的字符数是有问题的。备选案文1:
读取可能包含 * 空字符 * 的 * 行 *,并记录读取的字符数。
说明性代码(uncheck)使用
"%4096[^\n]"
读取一行的大部分内容(不是'\n'
),并使用"%n"
记录读取的字符数。备选案文2:
使用
fread()
读取数据块,并在找到第20个'\n'
时停止。使用memchr()
或使用循环查找'\n'
。