2016-01-29 11 views
5

Program rozpoznający wzór musi wydrukować wszystkie wiersze zawierające wzór, jeśli wejściowy wzór znajdzie. Jeśli wejście jest wzorcem find -x, program musi wydrukować wszystkie linie poza liniami zawierającymi wzór.Wyjaśnienie w sekcji 5.10 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++; 
     } 
    } 
// ...... 

W powyższym kodem z K & R z wyjątkiem może być albo 1 lub 0. W jaki sposób if(strstr...) funkcje blokowe skutecznie obsłużyć -x?

+0

Nie rozumiem pytania. Czy możesz rozwinąć? –

+0

Czy możesz zaktualizować swoje pytanie, aby pokazać definicję i inicjalizację 'except '? –

Odpowiedz

3

Logika jest prosta. Jeśli wzór jest "-x", powinniśmy wydrukować wszystkie linie, które nie zawierają wzorca.

Dla tego wzoru except jest równy 1.

So linie, które zawierają wzorzec spełniają warunek

strstr(line,*argv)!=NULL 

to jest warunek ten będzie zawsze równy 1 jeśli linia zawiera wzór.

Tak więc jeśli except jest równe 1, a warunek strstr(line,*argv)!=NULL jest równy 1, powinniśmy pominąć wzorzec.

W przeciwnym razie, jeśli warunek strstr(line,*argv)!=NULL nie jest równe 1 to jeśli wzór nie występuje wówczas, gdy oświadczenie

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

daje prawdziwy i jego oświadczenie związek jest wykonywany.

Z drugiej strony, jeśli except jest równa 0 potem do osiągnięcia, że ​​warunek w if by oceniać true musimy, że warunek strstr(line,*argv)!=NULL byłaby równa 1.

W rzeczywistości można przepisać if

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

następujący sposób

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

Krótko mówiąc if działa jeśli albo

1 and 0 

lub

0 and 1 

Jeśli któryś

1 and 1 

lub

0 and 0 

wtedy, gdy oświadczenie nie zostanie wykonany.

Tutaj 1 i 0 są wynikiem oceny dwóch podwyrażeń w instrukcji if.

3

nie jestem zaznajomiony z kodem, jednak to stwierdzenie oceni do Boolean (0 lub 1) jako strstr() zwróci wskaźnik do wyrazu poszukiwany lub NULL jeśli nie znaleziono:

strstr(line, *argv) != NULL 

Tak Domyślam się, że except jest ustawione na 0 lub 1, aby uzyskać efekt "nie został znaleziony" lub "został znaleziony".

Jeśli -x nie jest przekazywany następnie except jest 0:

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

co oznacza, jeśli słowo zostało znalezione wprowadzić klauzulę if.

Jeśli -x przechodzi następnie except jest 1:

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

co oznacza, jeśli słowo nie zostało znalezione wprowadzić klauzulę if.

To kod mylące, więc polecam go do zerwania:

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

} 

a następnie przechodzeniu z debuggera. Bardzo ważna jest również umiejętność korzystania z debuggera.

0

Operator != ma taką samą wartość prawdy jak operacja XOR. Więc można zerwać

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

do (mniej wydajne, ale może bardziej wyraźne)

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; 

Innymi słowy, except odwraca efekt tego, co się dzieje, gdy wzór znajduje się w ciąg.

Powiązane problemy