删除字符串开头和结尾的标点符号

问题描述:

我有一个字符串,我想从头尾开始删除所有标点符号,但不是中间的。删除字符串开头和结尾的标点符号

我已经写了代码,仅从一个字符串,这显然是非常低效的和无用的,如果一个字符串具有在2个月底或更多标点符号的第一个和最后一个字符删除标点。

下面是一个例子:

{ Hello ""I am:: a Str-ing!! } 

所需的输出

{ Hello I am a Str-ing } 

是否有任何功能,我可以用?谢谢。

这是我迄今为止所做的。实际上,我在编辑字符串链表

if(ispunct(removeend->string[(strlen(removeend->string))-1]) != 0) { 
    removeend->string[(strlen(removeend->string))-1] = '\0'; 
} 
else {} 
+1

如果我理解正确的话,你想移除每一* *字的两端标点符号一个给定的字符串? – cha0site 2012-07-07 12:59:18

+0

所以你实际上想要从字符串中的单词的开头和结尾去掉标点符号? – EricSchaefer 2012-07-07 12:59:40

+0

Wooble:发布编辑。 cha0site,EricSchaefer:是的,字符串中每个单词的开头和结尾。但不是中间。 – 2012-07-07 13:01:49

char *rm_punct(char *str) { 
    char *h = str; 
    char *t = str + strlen(str) - 1; 
    while (ispunct(*p)) p++; 
    while (ispunct(*t) && p < t) { *t = 0; t--; } 
    /* also if you want to preserve the original address */ 
    { int i; 
    for (i = 0; i <= t - p + 1; i++) { 
     str[i] = p[i]; 
    } p = str; } /* --- */ 

    return p; 
} 
+0

我的下一个问题是关于指针的转移,但是这突然出现并解决了我的问题。谢谢。 – 2012-07-07 14:27:03

+0

这不会在原始问题中的'I'之前抓住两个双引号。 – wildplasser 2012-07-07 14:42:25

遍历字符串,请使用因而isalpha()来检查每个字符,写一个进入一个新的字符串的字符。

+0

isalpha()将导致整个字符串变成字母,希望只在字符串的开头和结尾删除标点符号。 – 2012-07-07 13:26:40

遍历字符串,请使用isalpha()检查每个字符,即通过启动写入到一个新的字符串的第一个字符之后。

遍历新的字符串向后,替换所有的标点符号与\0,直到找到一个字符是不是标点符号。

+0

isalpha()会导致整个字符串变成字母,希望只在字符串的开头和结尾删除标点符号。除了我以为\ 0表示字符串结尾,我知道要在末尾替换\ 0和在开头替换为'',但是我怎么能保持中间部分的标点符号呢? – 2012-07-07 13:35:36

+0

@Lim:你误会了我。我的解决方案有2遍:首先,在字符串中找到**第一个非标点符号。 'isalpha()'对此很有用。一旦你有了,把所有东西都复制到一个新的字符串中。现在你有一个字符串,在开始时没有标点符号。现在,您可以通过用'\ 0'替换所有字符,直到找到非标点字符(向后遍历字符串),从最后删除标点符号。 – cha0site 2012-07-07 13:40:16

+0

为什么这会降低投票率? – cha0site 2012-07-07 13:45:41

好的,在while迭代中,多次调用strtok函数,以字符(空格)分隔每个单个字符串。您也可以使用sscanf而不是strtok

然后,对于每个字符串,你必须做一个for周期,但很快就从字符串到beginning.As年底开始,你遇到!isalpha(current character)在当前字符串位置放了\0。你已经消除了尾巴的标点符号。

现在,做相同的字符串另一for周期。现在从0strlen(currentstring)。虽然是!isalpha(current character)continue。如果isalpha将当前字符放在buffer和所有其余字符中。 buffer是已清理的字符串。将其复制到原始字符串中。

重复上述两个步骤为其他strtok的输出。结束。

#include <stdio.h> 
#include <ctype.h> 
#include <string.h> 

char* trim_ispunct(char* str){ 
    int i ; 
    char* p; 

    if(str == NULL || *str == '\0') return str; 
    for(i=strlen(str)-1; ispunct(str[i]);--i) 
     str[i]='\0'; 
    for(p=str;ispunct(*p);++p); 

    return strcpy(str, p); 
} 

int main(){ 
    //test 
    char str[][16] = { "Hello", "\"\"I", "am::", "a", "Str-ing!!" }; 
    int i, size = sizeof(str)/sizeof(str[0]); 
    for(i = 0;i<size;++i) 
     printf("%s\n", trim_ispunct(str[i])); 

    return 0; 
} 
/* result: 
Hello 
I 
am 
a 
Str-ing 
*/ 

构建一个微小的状态机。 cha2class()函数将字符分为等价类。状态机将总是跳过标点符号,除非它在左侧和右侧具有字母数字字符;在那种情况下它将被保留。 (即处于状态3的memmove())

#include <stdio.h> 
#include <string.h> 

#define IS_ALPHA 1 
#define IS_WHITE 2 
#define IS_PUNCT 3 
int cha2class(int ch); 
void scrutinize(char *str); 

int cha2class(int ch) 
{ 
if (ch >= 'a' && ch <= 'z') return IS_ALPHA; 
if (ch >= 'A' && ch <= 'Z') return IS_ALPHA; 
if (ch == ' ' || ch == '\t') return IS_WHITE; 
if (ch == EOF || ch == 0) return IS_WHITE; 
return IS_PUNCT; 
} 

void scrutinize(char *str) 
{ 
size_t pos,dst,start; 
int typ, state ; 

state = 0; 
for (dst = pos = start=0; ; pos++) { 
     typ = cha2class(str[pos]); 
     switch(state) { 
     case 0: /* BOF, white seen */ 
       if (typ==IS_WHITE) break; 
       else if (typ==IS_ALPHA) { start = pos; state =1; } 
       else if (typ==IS_PUNCT) { start = pos; state =2; continue;} 
       break; 
     case 1: /* inside a word */ 
       if (typ==IS_ALPHA) break; 
       else if (typ==IS_WHITE) { state=0; } 
       else if (typ==IS_PUNCT) { start = pos; state =3;continue; } 
       break; 
     case 2: /* inside punctuation after whitespace: skip it */ 
       if (typ==IS_PUNCT) continue; 
       else if (typ==IS_WHITE) { state=0; } 
       else if (typ==IS_ALPHA) {state=1; } 
       break; 
     case 3: /* inside punctuation after a word */ 
       if (typ==IS_PUNCT) continue; 
       else if (typ==IS_WHITE) { state=0; } 
       else if (typ==IS_ALPHA) { 
         memmove(str+dst, str+start, pos-start); dst += pos-start; 
         state =1; } 
       break; 
       } 
     str[dst++] = str[pos]; 
     if (str[pos] == '\0') break; 
     } 
} 
int main (int argc, char **argv) 
{ 
char test[] = ".This! is... ???a.string?" ; 

scrutinize(test); 

printf("Result=%s\n", test); 

return 0; 
} 

int main (int argc, char **argv) 
{ 
char test[] = ".This! is... ???a.string?" ; 

scrutinize(test); 

printf("Result=%s\n", test); 

return 0; 
} 

OUTPUT:

Result=This is a.string