如果输入是模式,模式识别程序必须打印包含模式的所有行。如果输入是find -x pattern,则程序必须打印除包含pattern的行以外的所有行。
// .....
switch(c)
{
case 'x':
except=1;
break;
// ......
}
// ......
while(getline(line,MAXLINE)>0)
{
line_num++;
if( (strstr(line,*argv)!=NULL) != except)
{
if(number)
printf("%ld:",linenum);
printf("%s",line);
found++;
}
}
// ......
在K& R的上述代码中,除了可以是1或0. if(strstr...)
如何有效地阻止函数处理-x?
答案 0 :(得分:3)
我不熟悉代码,但是此语句将评估为布尔值(0
或1
),因为strstr()
将返回指向要搜索的单词的指针或{{ 1}}如果没有找到:
NULL
所以我猜strstr(line, *argv) != NULL
设置为except
或0
以影响"未找到"或"被发现"条件。
如果未通过1
,则-x
为except
:
0
表示如果找到该单词,请输入if ((strstr(line, *argv) != NULL) != 0)
子句。
如果if
通过,则-x
为except
:
1
表示如果找到该单词,则不要输入if ((strstr(line, *argv) != NULL) != 1)
条款。
令人困惑的代码,所以我建议将其分解为:
if
然后单步调试。学习使用调试器也很重要。
答案 1 :(得分:3)
逻辑很简单。如果模式是"-x"
,我们应该打印所有不包含模式的行。
对于此模式,except
等于1
。
因此包含模式的行满足条件
strstr(line,*argv)!=NULL
如果一行包含模式,则此条件将始终等于1.
因此,如果except
等于1且条件strstr(line,*argv)!=NULL
等于1,我们应跳过该模式。
否则,如果条件strstr(line,*argv)!=NULL
不等于1,即如果未找到模式,那么if语句
if( (strstr(line,*argv)!=NULL) != except)
产生true并执行其复合语句。
另一方面,如果except
等于0
,那么为了实现if语句中的条件将评估为true,我们需要条件strstr(line,*argv)!=NULL
等于1
实际上你可以重写if语句
if( (strstr(line,*argv)!=NULL) != except)
以下方式
if( ( ( strstr(line,*argv) != NULL ) == 1 && except == 0 ) ||
( ( strstr(line,*argv) != NULL ) == 0 && except == 1 ) )
简而言之,如果
,则if语句可以正常工作1 and 0
或
0 and 1
如果
1 and 1
或
0 and 0
然后不会执行if语句。
这里1和0是在if语句中评估两个子表达式的结果。
答案 2 :(得分:0)
!=
运算符与XOR运算具有相同的真值。所以你可以分手
if( (strstr(line,*argv)!=NULL) != except)
{
if(number)
printf("%ld:",linenum);
printf("%s",line);
found++;
}
进入(效率低但可能更清晰)
char found_one_match;
if( strstr(line,*argv) != NULL )
{
found_one_match = 1;
}
else
{
found_one_match = 0;
}
found_one_match ^= except;
if (found_one_match)
{
if(number)
printf("%ld:",linenum);
printf("%s",line);
}
found += found_one_match;
换句话说,except
反转了在字符串中找到模式时发生的情况的影响。