8

Cで先頭と末尾のスペースを削除するための最良のアプローチは何ですか?

4

16 に答える 16

24

Linuxカーネルがstrstrip()と呼ばれるトリミングを行う方法は次のとおりです。

char *strstrip(char *s)
{
    size_t size;
    char *end;

    size = strlen(s);

    if (!size)
        return s;

    end = s + size - 1;
    while (end >= s && isspace(*end))
        end--;
    *(end + 1) = '\0';

    while (*s && isspace(*s))
        s++;

    return s;
}

その基本的には、前のポスターが言ったことをより適切にフォーマットし、エラーチェックしたバージョンです。

于 2008-12-09T08:27:30.663 に答える
9

この質問は宿題の質問のように見えるので、斜めに答えます: isspace(3) と strlen(3) のマニュアルページを調べて、ポインター演算を使用してください。また、目前の問題によっては、結果のスペースを保持するために malloc(3) が必要になる場合があります。

C 文字列の表現には末尾の 0 バイトが含まれていることを忘れないでください。これは多くの場合、'\0' と書かれますが、これは文字列の長さの一部としてカウントされません。

于 2008-12-09T08:03:24.173 に答える
8

isspace を使用したバージョンは次のとおりです。

char * trim(char *c) {
    char * e = c + strlen(c) - 1;
    while(*c && isspace(*c)) c++;
    while(e > c && isspace(*e)) *e-- = '\0';
    return c;
}
于 2008-12-09T08:52:53.747 に答える
5

これは完全に適切に行うことができます。

 void stripLeadingAndTrailingSpaces(char* string){

     assert(string);

     /* First remove leading spaces */

     const char* firstNonSpace = string;

     while(*firstNonSpace != '\0' && isspace(*firstNonSpace))
     {
          ++firstNonSpace;
     }

     size_t len = strlen(firstNonSpace)+1;         

     memmove(string, firstNonSpace, len);

     /* Now remove trailing spaces */

     char* endOfString = string + len;

     while(string < endOfString  && isspace(*endOfString))
     {
          --endOfString ;
     }

     *endOfString = '\0';

}
于 2008-12-09T08:32:46.097 に答える
3
char *strstrip(char *s)
{
    char *end;

    while ( (*s) && isspace( *s))
        s++;

    if(!( *s) )
        return s;
    end = s;

    while( ! *end)
        end++;
    end--;

    while (end ! = s && isspace( *end))
        end--;
    *(end + 1) = '\0';

    return s;
}

これは基本的に、より最適化されたコードです (速度とコードサイズの点で)。

メモリ空間を保持する必要がある場合は、

void strstrip(char *s)
{
    char *start;
    char *end;

    start = s; 
    while ( (*start) && isspace( *start))
        start++;

    if(!( *start) ) 
    {
        *s='\0';
        return ;
    }
    end = start;

    while( ! *end)
        end++;
    end--;

    while (end ! = start && isspace( *end))
        end--;
    *(end + 1) = '\0';

    memmove(s, start, end-start+1);

    return;
}
于 2008-12-09T09:19:24.817 に答える
3

以下は、lakshmanaraj の最初の関数のより簡潔で安全なバージョンです。

#include <ctype.h>
char *mytrim(char *s)
{
    if(s) { /* Don't forget to check for NULL! */
        while(*s && isspace(*s))
            ++s;
        if(*s) {
            register char *p = s;
            while(*p)
                ++p;
            do {
                --p;
            } while((p != s) && isspace(*p));
            *(p + 1) = '\0';
        }
    }
    return(s);
}
于 2009-01-05T09:52:36.390 に答える
2

上記の別の投稿の改良。

void  strstrip( char *s )
{
  char *start;
  char *end;

  // Exit if param is NULL pointer
  if (s == NULL)
    return;

  // Skip over leading whitespace
  start = s;
  while ((*start) && isspace(*start))
    start++;      

  // Is string just whitespace?
  if (!(*start)) 
  {         
    *s = 0x00; // Truncate entire string
    return;     
  }     

  // Find end of string
  end = start;
  while (*end)         
    end++;     

  // Step back from NUL
  end--;      

  // Step backward until first non-whitespace
  while ((end != start) && isspace(*end))         
    end--;     

  // Chop off trailing whitespace
  *(end + 1) = 0x00;

  // If had leading whitespace, then move entire string back to beginning
  if (s != start)
    memmove(s, start, end-start+1);      

  return; 
} 
于 2011-01-06T03:20:27.397 に答える
1

末尾の空白には strtok を使用します。delimiter = " " を設定し、実行時に delimiter バイトを破棄して char * をトークンに返します

char *x;
char *y = "somestring "; 

x = strtok(y," ");

結果 x = 「somestring」ではなく「somestring」へのポインター

于 2015-10-16T20:27:49.887 に答える
1
int i = strlen(s) - 1;
while (isspace(s[i]))
    s[i--] = '\0';
while (isspace(*s))
    s++;

狂ったように文字列を台無しにすることを気にしない限り、そしてメモリリークを気にしない限り、それは問題を処理するはずです!

于 2008-12-09T08:04:30.537 に答える
1

インプレースで実行できるはずです。空白を削除しても、文字列が大きくなることはありません。最初に文字列の長さをチェックしなくてもできるかもしれませんが、そうするのは不必要に「賢い」かもしれません。memmove()@Norman Ramseyが言及したものに加えて、関数を調べる必要があります。

于 2008-12-09T08:10:00.667 に答える
1

Linux/Windows を使用していて、ライブラリ glib がプログラムにリンクされている場合は、ルーチンを使用できますg_strstrip()

于 2009-01-05T06:08:33.457 に答える
1

編集: zString ライブラリの最新バージョンに基づいてコードを更新しました。

このコードはライブラリに依存せず、ポインタ演算と整数のみに依存しています。トリム、左トリム、右トリムの 3 つの機能があります。(これらすべての関数をzString ライブラリに追加する必要があります:))

  • char *zstring_trim(char *s)先頭と末尾の空白を削除します

  • char *zstring_ltrim(char *s)先頭の空白を削除します

  • char *zstring_ltrim(char *s)末尾の空白を削除します

これらの関数はすべて元の文字列を変更します

/* trim */
char *zstring_trim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    char c;
    int is_space=0;
    int in_word=0;  /* word boundary logical check */
    int index=0;    /* index of the last non-space char*/

    /* validate input */
    if (!str)
        return str;

    while ((c=*src)){
        is_space=0;

        if (c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r' || c==' ')
            is_space=1;

        if(is_space == 0){
         /* Found a word */
            in_word = 1;
            *dst++ = *src++;  /* make the assignment first
                               * then increment
                               */
        } else if (is_space==1 && in_word==0) {
         /* Already going through a series of white-spaces */
            in_word=0;
            ++src;
        } else if (is_space==1 && in_word==1) {
         /* End of a word, dont mind copy white spaces here */
            in_word=0;
            *dst++ = *src++;
            index = (dst-str)-1; /* location of the last char */
        }
    }

    /* terminate the string */
    *(str+index)='\0';

    return str;
}

/* right trim */
char *zstring_rtrim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    char c;
    int is_space=0;
    int index=0;    /* index of the last non-space char */

    /* validate input */
    if (!str)
        return str;

    /* copy the string */
    while(*src){
        *dst++ = *src++;
        c = *src;

        if (c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r' || c==' ')
            is_space=1;
        else
            is_space=0;

        if (is_space==0 && *src)
            index = (src-str)+1;
    }

    /* terminate the string */
    *(str+index)='\0';

    return str;
}

/* left trim */
char *zstring_ltrim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    char c;
    int index=0;    /* index of the first non-space char */

    /* validate input */
    if (!str)
        return str;

    /* skip leading white-spaces */
    while((c=*src)){ 
        if (c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r' || c==' '){
            ++src;
            ++index;
        } else
            break;
    }

    /* copy rest of the string */
    while(*src)
        *dst++ = *src++;

    /* terminate the string */
    *(src-index)='\0';

    return str;
}
于 2016-02-25T02:05:15.373 に答える
1
char *strip(char *string)
{
    char *start = string;
    while(isblank(*start)) start++;
    int end = strlen(start);
    if(start != string) {
        memmove(string, start, end);
        string[end] = '\0';
    }
    while(isblank(*(string+end-1))) end--;
    string[end] = '\0';
    return string;
}
于 2014-01-17T19:26:43.000 に答える
1

fpsgamer からの相関アルゴリズム (ISO C90 も有効):

void trimWhitespace(char *string) {
    const char* firstNonSpace = string;
    char* endOfString;
    size_t len;

    if (string[0] == '\0') {
        return;
    }

    /* First remove leading spaces */
    while(*firstNonSpace != '\0' && isspace(*firstNonSpace)) {
        ++firstNonSpace;
    }
    len = strlen(firstNonSpace) + 1;
    memmove(string, firstNonSpace, len);

    /* Now remove trailing spaces */
    endOfString = string + len;

    while(string < endOfString && (isspace(*endOfString) || *endOfString == '\0')) {
        --endOfString ;
    }

    *(endOfString + 1) = '\0';
}
于 2014-04-22T23:22:55.790 に答える