2011-09-06 16 views
5

Zrobiłem program, który usunie znaki wewnątrz nawiasów. Wprowadzony tekst powinien mieć zgodny nawias otwierający i zamykający.Usuwanie znaków z nawiasów w C

Przypadek 1:

Wejście:       (Hello) World
wyjściowa: World

Przypadek 2:

Wejście:       (Hello World
wyjściowa: (Hello World

Przypadek 3:

Wejście:       Hello)(World
wyjściowa: Hello)(World

Przypadek 4:

Wejście:       Hello((hi) World)
wyjściowa: Hello

Przypadek 5:

Wejście:       (Hello) hi (World)
wyjściowa: hi

Oto mój kod:

#include <stdio.h> 
int main(){ 
    char string[100] = {0}; 
    char removedletters[100] = {0}; 
    fgets(string, 100, stdin); 
    char *p; 
    int x = 0; 
    int b = 0; 
    for (p=string; *p!=0; p++) { 
     if (*(p-1) == '(' && x) { 
      x = 0; 
     } 
     if (*p == ')') { 
      x = 1; 
     } 
     if (!x){ 
      removedletters[b] = *p; 
      b++; 
     } 
    } 
    puts(removedletters); 
} 

Przypadek 1, 3 i 5 są poprawne, ale nie w przypadku 2 i 4. Co źle z moim kodem?

+0

użycie strchr zamiast szukać ręcznie poprzez ciąg – thumbmunkeys

+0

'if (* (p-1)' jest niezdefiniowane zachowanie dla pierwszej iteracji. – Mat

+0

+1 Witamy stackoverflow! Wspaniałe pierwsze pytanie. – phihag

Odpowiedz

2

Jesteś powołując niezdefiniowane zachowanie:

for(p=string; *p!=0; p++){ 
    if(*(p-1) == '(' && x){ 
     x = 0; 
    } 

Pierwszy raz p++ jest oceniana jest na końcu pętli bloku, dlatego, po raz pierwszy, *(p-1) wskazuje nikogo z string, tzn robią *(string-1).

Niestety utracisz gwarancję, jeśli masz niezdefiniowane zachowanie.

1

Nie jestem pewien, co jest szczególnie nie tak z tym kodem, ale ze względu na efektywność trzymam stos ostatnio znalezionych znaków ( i używam go do usuwania fragmentów, gdy tylko znajdziesz ).

w Semi-Pseudokod:

// str is the input string, set up to and from pointers. 
stacktype stack = empty-stack 
char *from = str 
char *to = str 

// Process every character once and once only. 
while *from != '\0': 
    switch *from: 
     // Open, transfer character and store position on stack. 
     case '(': 
      *to++ = *from++ 
      stack.push (to - 1) 
      break 

     // Close, get most recent '(' and adjust to for overwrite. 
     // If no most recent, just transfer as is. 
     case ')': 
      if stack is not empty: 
       to = stack.pop() 
      else: 
       *to++ = *from++ 
      break 

     // Anything else, just transfer. 
     default: 
      *to++ = *from++ 

// Terminate string at truncated position. 
*to = '\0' 

Pozwoli to przejść przez ciąg znaków po znaku, pamiętając o wszystkich ( pozycji w stosie, ale wciąż przeniesienie znaków.

Kiedykolwiek znaleźć ) charakter, wyregulować wskaźnik to tak że zaczniesz nadpisywania od najnowszego ( charakterze, skutecznie usuwając wszystko, co wewnątrz i tym sekcję (...).

Powiązane problemy