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

时间:2012-07-07 12:56:38

标签: c

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

我编写了一个代码来删除字符串的第一个和最后一个字符的标点符号,如果字符串末尾有两个或更多的标点符号,这显然效率很低而且无用。

以下是一个例子:

{ 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 {} 

6 个答案:

答案 0 :(得分:2)

迭代字符串,使用isalpha()检查每个字符,写入传递给新字符串的字符。

答案 1 :(得分:0)

迭代字符串,在第一个开始写入新字符串的字符后,使用isalpha()检查每个字符。

向后迭代新字符串,将所有标点符号替换为\0,直到找到不是标点符号的字符。

答案 2 :(得分:0)

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

然后,对于每个字符串,您必须执行for周期,但从字符串的结尾开始直到开头。遇到!isalpha(current character)时,只需\0 for在当前字符串位置。你已经消除了尾巴的标点字符。

现在,在同一个字符串上再做一次0循环。现在从strlen(currentstring)!isalpha(current character)。虽然是continue isalpha。如果buffer将当前字符放入buffer和所有剩余字符中。 strtok是已清理的字符串。将其复制到原始字符串中。

对其他{{1}}的输出重复上述两个步骤。端。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

#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
*/

答案 5 :(得分:-1)

构建一个小型状态机。 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;
}

输出:

Result=This is a.string