2016-01-29 9 views
5

Ein Mustererkennungsprogramm muss alle Zeilen mit dem Muster drucken, wenn die Eingabe ein Suchmuster ist. Wenn die Eingabe das Muster "find -x" ist, muss das Programm alle Zeilen außer den Zeilen mit dem Muster drucken.Erläuterung in Abschnitt 5.10 von K & R 2

// ..... 
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 dem obigen Code von K & R außer kann entweder 1 oder 0. Wie if(strstr...) Blockfunktionen effektiv zu handhaben -x?

+0

Ich habe die Frage nicht verstanden. Kannst du es ausarbeiten? –

+0

Können Sie Ihre Frage aktualisieren, um die Definition und Initialisierung von 'except' anzuzeigen? –

Antwort

3

Die Logik ist einfach. Wenn das Muster "-x" ist, sollten wir alle Zeilen drucken, die das Muster nicht enthalten.

Für dieses Muster ist except gleich 1.

So Linien, die das Muster enthalten, erfüllen die Bedingung

strstr(line,*argv)!=NULL 

, die diese Bedingung gleich 1 ist immer sein wird, wenn eine Linie, die Muster enthält. Wenn also except gleich 1 ist und die Bedingung strstr(line,*argv)!=NULL gleich 1 ist, sollten wir das Muster überspringen.

Andernfalls, wenn die Bedingung strstr(line,*argv)!=NULL nicht gleich 1 das heißt, wenn das Muster nicht gefunden wird, dann die if-Anweisung

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

ergibt wahr und seine Verbindung Anweisung ausgeführt wird.

Auf der anderen Seite, wenn except gleich 0 dann zu erreichen, dass die Bedingung in der if-Anweisung true bewerten würden wir brauchen, dass die Bedingung strstr(line,*argv)!=NULL wäre gleich zu 1.

In der Tat Sie das neu schreiben kann if-Anweisung

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

die folgende Art und Weise

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

Kurz gesprochen die if-Anweisung macht die Arbeit, wenn entweder

1 and 0 

oder

0 and 1 

Wenn entweder

1 and 1 

oder

0 and 0 

dann die if-Anweisung nicht ausgeführt wird.

Hier sind 1 und 0 Ergebnisse der Auswertung der beiden Unterausdrücke in der if-Anweisung.

3

Ich bin nicht mit dem Code vertraut, aber diese Aussage auf einen boolean auswertet (0 oder 1) als strstr() einen Zeiger auf Wort zurückzukehren für oder NULL gesucht wird, wenn nicht gefunden:

strstr(line, *argv) != NULL 

So Ich nehme an, dass except auf 0 oder 1 eingestellt ist, um die Bedingung "wurde nicht gefunden" oder "wurde gefunden" zu erhalten.

Wenn -x nicht dann übergeben wird except ist 0:

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

was bedeutet, wenn das Wort die if Klausel eingeben gefunden wurde.

Wenn -x geführt wird dann except ist 1:

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

was bedeutet, wenn das Wort die if Klausel nicht eingeben gefunden wurde.

Es ist verwirrend Code, so würde ich empfehlen, es zu brechen:

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

} 

und dann mit einem Debugger Schreiten durch. Der Einsatz eines Debuggers ist ebenfalls wichtig.

0

Der Operator != hat den gleichen Wahrheitswert wie eine XOR-Operation. So können Sie

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

in (weniger effizient, aber vielleicht klarer)

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; 

Mit anderen Worten brechen, except kehrt die Wirkung dessen, was passiert, wenn ein Muster in der Zeichenfolge gefunden wird.