开发者

Removing characters inside parenthesis in C

开发者 https://www.devze.com 2023-04-02 11:55 出处:网络
I made a program that will delete characters inside a parenthesis. The inputted text should have matching open and close parenthesis.

I made a program that will delete characters inside a parenthesis. The inputted text should have matching open and close parenthesis.

Case 1:

Inpu开发者_JAVA技巧t:    (Hello) World

Output: World

Case 2:

Input:    (Hello World

Output: (Hello World

Case 3:

Input:    Hello)(World

Output: Hello)(World

Case 4:

Input:    Hello((hi) World)

Output: Hello

Case 5:

Input:    (Hello) hi (World)

Output: hi

Here's my code:

#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);
}

Case 1, 3, and 5 are correct, but not in Case 2 and 4. What's wrong with my code?


You are invoking undefined behaviour:

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

The first time p++ is evaluated is at the end of the loop-block, therefore, for the first time, *(p-1) is pointing one left of string, i.e. you are doing *(string-1).

Unfortunately, you lose any warranty if you have undefined behaviour.


I'm not sure what's specifically wrong with that code but, for efficiency, I'd keep a stack of the last found ( characters and use that to remove portions whenever you find a ).

In semi-pseudocode:

// 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'

This will go through the string character by character, remembering all the ( positions in the stack but still transferring characters.

Whenever you find a ) character, you adjust the to pointer so that you start overwriting from the most recent ( character, effectively removing everything inside and including a (...) section.

0

精彩评论

暂无评论...
验证码 换一张
取 消