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
World
Case 2:
Input: (Hello World
(Hello World
Case 3:
Input: Hello)(World
Hello)(World
Case 4:
Input: Hello((hi) World)
Hello
Case 5:
Input: (Hello) hi (World)
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.
精彩评论