删除C中括号内的字符

时间:2011-09-06 09:22:34

标签: c arrays string pointers

我制作了一个删除括号内字符的程序。输入的文本应该具有匹配的开括号和右括号。

案例1:

输入:(Hello) World
输出:World

案例2:

输入:(Hello World
输出:(Hello World

案例3:

输入:Hello)(World
输出:Hello)(World

案例4:

输入:Hello((hi) World)
输出:Hello

案例5:

输入:(Hello) hi (World)
输出:hi

这是我的代码:

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

案例1,3和5是正确的,但不是案例2和案例4。 我的代码出了什么问题?

2 个答案:

答案 0 :(得分:2)

您正在调用未定义的行为:

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

第一次评估p++是在循环块的末尾,因此,*(p-1)第一次指向string的左边,即你正在做*(string-1)

不幸的是,如果您有未定义的行为,您将失去任何保修。

答案 1 :(得分:1)

我不确定该代码有什么特别的错误,但为了提高效率,我会保留最后找到的(个字符的堆栈,并在找到)时使用它来删除部分

半伪代码:

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

这将逐个字符串,逐字符号,记住堆栈中的所有(位置,但仍会传输字符。

每当您找到)字符时,都会调整to指针,以便从最新的(字符开始覆盖,有效删除内部的所有内容,包括(...) }。section。