关了手机,定好机械闹钟,一心就把上午读的几个代码写写心得。
wc 这个命令用得很熟悉了,看《flex and bison》中编写一个wc是很简单的,但打开看,wc.c命令也有几百行,596行。
从main开始说起,我读代码是从头到尾看,我总想全部翻一次,再慢慢从尾到头分析。main中,根据传入文件的多少,如果传入多个文件,再打印一个合计信息。
我验证了一下,果然如此。
for (; optind < argc; ++optind)
wc_file (argv[optind]);
if (nfiles > 1)
write_counts (total_lines, total_words, total_chars, total_bytes,
max_line_length, _("total"));
其实我难的方法就是再加一句打印语句,读程序时,若找不清头绪,我就根据自己的大致推测,加打印语句。
所以干活的主要是wc_file这个函数。
wc_file调用wc来解决问题
wc (fd, file);
再看wc
程序用几个变量来累计计算的结果
lines = words = chars = bytes = linelength = 0;
主要的结构是一个大的if语句。
if (count_bytes && !count_chars && !print_lines && !count_complicated)
{
}
else if (!count_chars && !count_complicated)
{
}
其中还有宏的一段,不管了,其实开头是有注释的,
/* When counting only bytes, save some line- and word-counting
overhead. If FD is a `regular' Unix file, using lseek is enough
to get its `size' in bytes. Otherwise, read blocks of BUFFER_SIZE
bytes at a time until EOF. Note that the `size' (number of bytes)
that wc reports is smaller than stats.st_size when the file is not
positioned at its beginning. That's why the lseek calls below are
necessary. For example the command
`(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
should make wc report `0' bytes. */
write_counts (total_lines, total_words, total_chars, total_bytes,
max_line_length, _("total"));
其实我难的方法就是再加一句打印语句,读程序时,若找不清头绪,我就根据自己的大致推测,加打印语句。
所以干活的主要是wc_file这个函数。
wc_file调用wc来解决问题
wc (fd, file);
再看wc
程序用几个变量来累计计算的结果
lines = words = chars = bytes = linelength = 0;
主要的结构是一个大的if语句。
if (count_bytes && !count_chars && !print_lines && !count_complicated)
{
}
else if (!count_chars && !count_complicated)
{
}
其中还有宏的一段,不管了,其实开头是有注释的,
/* When counting only bytes, save some line- and word-counting
overhead. If FD is a `regular' Unix file, using lseek is enough
to get its `size' in bytes. Otherwise, read blocks of BUFFER_SIZE
bytes at a time until EOF. Note that the `size' (number of bytes)
that wc reports is smaller than stats.st_size when the file is not
positioned at its beginning. That's why the lseek calls below are
necessary. For example the command
`(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
should make wc report `0' bytes. */
/* Use a separate loop when counting only lines or lines and bytes --
but not chars or words. */
这段注释我看,大致就是计算行数的处理在此。于是就加打印语句,看它是否走到这儿,执行时,果然走到这里。
else if (!count_chars && !count_complicated)
{
/* Use a separate loop when counting only lines or lines and bytes --
but not chars or words. */
while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
{
register char *p = buf;
but not chars or words. */
这段注释我看,大致就是计算行数的处理在此。于是就加打印语句,看它是否走到这儿,执行时,果然走到这里。
else if (!count_chars && !count_complicated)
{
/* Use a separate loop when counting only lines or lines and bytes --
but not chars or words. */
while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
{
register char *p = buf;
while ((p = memchr (p, '\n', (buf + bytes_read) - p)))
{
++p;
++lines;
}
bytes += bytes_read;
}
if (bytes_read < 0)
{
error (0, errno, "%s", file);
exit_status = 1;
}
从代码看,就是看有几个\n,就认为有几行。用的memchr库函数没用过,我在想,争对一些特殊情况,这段代码是正确的吗?后来就想,如果仔细调的话,不划算,先留点尾巴。以后典再看吧。
{
++p;
++lines;
}
bytes += bytes_read;
}
if (bytes_read < 0)
{
error (0, errno, "%s", file);
exit_status = 1;
}
从代码看,就是看有几个\n,就认为有几行。用的memchr库函数没用过,我在想,争对一些特殊情况,这段代码是正确的吗?后来就想,如果仔细调的话,不划算,先留点尾巴。以后典再看吧。