-1

この質問は、C で文字列をトリミングするためのガイドとして使用しています。空白 ( ) だけで囲まれた文字列では適切に機能します' 'が、特殊な空白 ( '\r''\n''\t'など) では失敗します。次に例を示します。

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

size_t trim(char *out, size_t len, const char *str)
{
  if(len == 0)
    return 0;

  const char *end;
  size_t out_size;

  // Trim leading space
  while(isspace(*str)) str++;

  if(*str == 0)  // All spaces?
  {
    *out = 0;
    return 1;
  }

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace(*end)) end--;
  end++;

  // Set output size to minimum of trimmed string length and buffer size minus 1
  out_size = (end - str) < len-1 ? (end - str) : len-1;

  // Copy trimmed string and add null terminator
  memcpy(out, str, out_size);
  out[out_size] = 0;

  return out_size;
}

int main(){

    char *str = " \n\n  hello  \t    \r  ";
    char trimmed[strlen(str)];

    trim (trimmed, strlen(trimmed), str);
    printf("~%s~\n~%s~\n", str, trimmed);

    return 0;
}

出力を生成します:

~ 

  ~ello         
~~

すべての空白文字を適切にトリミングするようにコードを修正できる人はいますか?

2 番目の質問: 参照されている回答の最初の関数で、segfault が発生します。なぜこれが事実なのか誰か知っていますか?

4

3 に答える 3

2

関数の呼び出し方が間違っています。

char *str = " \n\n  hello  \t    \r  ";
char trimmed[strlen(str)+1]; // Note that you must +1 for the terminating \0.

// Use sizeof() instead of strlen() because trimmed is containing garbage.
// strlen() measures the length of the content while sizeof() measure the allocated size of the array.
trim (trimmed, sizeof(trimmed), str); 
于 2012-08-10T16:37:27.053 に答える
0

isspace の代わりに、または isspace に加えて isgraph を試す

于 2012-08-10T16:31:36.647 に答える
-1

ただし、特殊な空白 ('\r'、'\n'、'\t' など) では失敗します。

C では、文字はunsigned integersであるため、 と言えば、その ASCII コードは 10 進数で 32、16 進数で 0x20 であるwhite-spaceことがわかります。' 'あなたが言及した文字は空白ではありません!

' ' != '\r'

以下は、trimleft-trim、およびright-trim関数の実装で、文字列からそれぞれ周囲 (つまり、先頭と末尾)、先頭と末尾の空白を削除します。関数は余分なヘッダーを必要とせず、整数とポインター演算のみに依存する最も可能性のあるベアボーン実装です。

必要に応じてコードを変更できます (あなたの場合、投稿で言及した 、 、などのif他の文字をカバーするために論理ケースを拡張する必要があります)。\r\n\t

これらの関数を文字列ライブラリ zStringに追加します:)

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

    while (*src)
        if(*src!=' '){
         /* Found a word */
            in_word = 1;
            *dst++ = *src++;  /* make the assignment first
                               * then increment
                               */
        } else if (*src==' ' && in_word==0) {
         /* Already going through a series of white-spaces */
            in_word=0;
            ++src;
        } else if (*src==' ' && 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;
}

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

    /* skip leading white-spaces */
    for(; *src && *src==' '; ++src, ++index)
        ;

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

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

    return str;
}

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

    /* copy the string */
    while(*src){
        *dst++ = *src++;
        if (*src!=' ' && *src)
            index = (src-str)+1;
    }

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

    return str;
}
于 2016-02-24T21:17:12.900 に答える