【问题标题】:Removing characters inside parenthesis in C在C中删除括号内的字符
【发布时间】:2011-09-06 09:22:34
【问题描述】:

我做了一个程序,可以删除括号内的字符。输入的文本应该有匹配的左括号和右括号。

案例一:

输入:   (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 中不正确。 我的代码有什么问题?

【问题讨论】:

  • 使用 strchr 而不是手动搜索字符串
  • if(*(p-1) 是第一次迭代的未定义行为。
  • +1 欢迎使用 stackoverflow!第一个问题很好。
  • *(p-1) 当 p=string 时可以是任何东西
  • 您的removedletters 字符串由您提到的输出组成?

标签: c arrays string pointers


【解决方案1】:

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

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

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

很遗憾,如果您有未定义的行为,您将失去任何保修。

【讨论】:

    【解决方案2】:

    我不确定该代码有什么具体问题,但为了提高效率,我会保留最后找到的 ( 字符的堆栈,并在您找到 ) 时使用它来删除部分。

    在半伪代码中:

    // 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 指针,以便从最近的( 字符开始覆盖,从而有效地删除其中的所有内容,包括(...) 部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 2012-01-28
      • 2021-12-31
      • 1970-01-01
      相关资源
      最近更新 更多