gnu coreutils-4.5.1 comm.c代码分析3
下班后,接着读代码,开始心情有些浮躁,冥想片刻,心静下来,再细心读,不觉忘记了烦恼。
先准备两个文件
cat test01
内容为
1
2
3
4
cat test02
3
4
5
6
再测试一下,
comm test01 test02
1
2
5
6
3
4
大致输出如下,但代码writeline()就是理解不了。
如果加打印语句,把case 3中的一个\t去掉,发现输出结果就变了。
但为什么会变呢?
static void
writeline (const struct linebuffer *line, FILE *stream, int class)
{
switch (class)
{
case 1:
if (!only_file_1)
return;
break;
case 2:
if (!only_file_2)
return;
/* Print a TAB if we are printing lines from file 1. */
if (only_file_1)
putc ('\t', stream);
break;
case 3:
if (!both)
return;
/* Print a TAB if we are printing lines from file 1. */
if (only_file_1)
putc ('\t', stream);
/* Print a TAB if we are printing lines from file 2. */
if (only_file_2)
putc ('\t', stream);
break;
}
fwrite (line->buffer, sizeof (char), line->length, stream);
}
为什么在case 3:中,要再判断only_file_1,only_file_2呢?我百思不得其解。
回过头看
compare_files (char **infiles)
if (!thisline[0])
order = 1;
else if (!thisline[1])
order = -1;
else
{
if (HAVE_SETLOCALE && hard_LC_COLLATE)
order = xmemcoll (thisline[0]->buffer, thisline[0]->length - 1,
thisline[1]->buffer, thisline[1]->length - 1);
else
{
size_t len = min (thisline[0]->length, thisline[1]->length) - 1;
order = memcmp (thisline[0]->buffer, thisline[1]->buffer, len);
if (order == 0)
order = (thisline[0]->length < thisline[1]->length
? -1
: thisline[0]->length != thisline[1]->length); //????
}
}
其中加?的那句,终于理解了,因为从两个文件件中,各读一行,如果哪个文件读完了,那就结果分晓了。如果两个文件都能读到内容,再找出两行长度的最小值,比较前相同的N个字符,若前N个字符相等,再看谁的长度大,如果thisline[0].length<thisline[1].length,那么前者小,如果两者长度相等,则返回0,如果thisline[0].length>thisline[1].length,则为1,也就是
: thisline[0]->length != thisline[1]->length); //????
表达了两种意思。作者的代码写得象珍珠,没有一点多余的废话,佩服。