Clarification in Section 5.10 K & R 2

The pattern recognition program should print all lines containing a patter if the input pattern is in search. If an -x pattern is found at the input, the program should print all lines except lines containing the template.

// ..... 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++; } } // ...... 

In the above code, K & R except can be 1 or 0. How are efficient if(strstr...) functions to handle -x efficiently?

+5
source share
3 answers

The logic is simple. If the pattern is "-x" , we must print all lines that do not contain the pattern.

For this pattern, except is 1 .

Thus, the lines containing the pattern satisfy the condition

 strstr(line,*argv)!=NULL 

then this condition will always be 1 if the string contains a pattern.

Thus, if except is 1 and the condition strstr(line,*argv)!=NULL is 1, we must skip the pattern.

Otherwise, if the condition strstr(line,*argv)!=NULL not 1, that is, if the pattern is not found, the if statement

 if( (strstr(line,*argv)!=NULL) != except) 

returns true, and its compound statement is executed.

On the other hand, if except is 0 , then to ensure that the condition in the if expression evaluates to true, we need the condition strstr(line,*argv)!=NULL to be 1.

In fact, you can rewrite the if statement

 if( (strstr(line,*argv)!=NULL) != except) 

in the following way

 if( ( ( strstr(line,*argv) != NULL ) == 1 && except == 0 ) || ( ( strstr(line,*argv) != NULL ) == 0 && except == 1 ) ) 

In short, the if statement does the job if either

 1 and 0 

or

 0 and 1 

If either

 1 and 1 

or

 0 and 0 

then the if statement will not be executed.

Here 1 and 0 are the results of evaluating two subexpressions in the if expression.

+3
source

I am not familiar with the code, but this operator will calculate a boolean value ( 0 or 1 ), since strstr() will return a pointer to a word search or NULL if not found:

 strstr(line, *argv) != NULL 

So, I suppose that except set to 0 or 1 to fulfill the condition "was not found" or "was found."

If -x not passed, then except is 0 :

 if ((strstr(line, *argv) != NULL) != 0) 

which means that if the word is found, enter the if clause.

If -x is passed, then except is 1 :

 if ((strstr(line, *argv) != NULL) != 1) 

which means that if a word is found, do not enter an if clause.

This is confusing code, so I would recommend breaking it down into:

 const char *word = strstr(line,*argv); int wasfound = word != NULL; if (wasfound != except) { } 

and then going through the debugger. Learning about using a debugger is also vital.

+3
source

The != Operator has the same true meaning as the XOR operation. So you can break

 if( (strstr(line,*argv)!=NULL) != except) { if(number) printf("%ld:",linenum); printf("%s",line); found++; } 

in (less effective, but perhaps more understandable)

 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; 

In other words, except cancels the effect of what happens when the pattern is found in the string.

0
source

Source: https://habr.com/ru/post/1241784/


All Articles