7

重複の可能性:
C で先頭/末尾の空白を削除する簡単な方法は?
C で文字列をトリミングする

私は c で文字列トリム メソッドを書いていましたが、これが思いついたコードです。先頭と末尾の空白を削除する仕事をしていると思いますが、コードがよりきれいになることを願っています。改善を提案できますか?

void trim(char *String)
{
int i=0;j=0;
char c,lastc;
while(String[i])
{
   c=String[i];
   if(c!=' ')
   {
     String[j]=c;
     j++;
   }
   else if(lastc!= ' ')
   {
     String[j]=c;
     j++;

   }
   lastc = c;
   i++;
}

このコードはきれいに見えますか??

4

7 に答える 7

4

きれいに見えません。最初の文字がスペースであると仮定するlastcと、未定義の値で使用しています。最後に1つのスペースを残しています(最後にスペースがある場合、ヒットcするとスペースにlastcなりません)。

また、文字列を終了していません。初期化されていない問題を修正すると仮定すると、lastc「abc」は「abcbc」に変換されます。これは、どの時点でも短縮されていないためです。

このコードは、文字列内の複数のスペースも折りたたみます。これはあなたが説明したものではありません。それは望ましい行動ですか?

于 2010-03-15T21:54:21.707 に答える
3

標準ライブラリ関数を適切に使用すると、多くの場合、コードが読みやすくなります。たとえば、次の場合isspace()memmove()特に役立ちます。

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

void trim(char *str)
{
    char *start, *end;

    /* Find first non-whitespace */
    for (start = str; *start; start++)
    {
        if (!isspace((unsigned char)start[0]))
            break;
    }

    /* Find start of last all-whitespace */
    for (end = start + strlen(start); end > start + 1; end--)
    {
        if (!isspace((unsigned char)end[-1]))
            break;
    }

    *end = 0; /* Truncate last whitespace */

    /* Shift from "start" to the beginning of the string */
    if (start > str)
        memmove(str, start, (end - start) + 1);
}
于 2010-03-15T22:38:38.110 に答える
1

これが私の解決策です。

短く、シンプルで、クリーンで、コメントが付けられ、軽くテストされています。

「isspace」分類機能を使用しているため、トリミングする「空白」の定義を簡単に変更できます。

void trim(char* String)
{
    int dest;
    int src=0;
    int len = strlen(String);

    // Advance src to the first non-whitespace character.
    while(isspace(String[src])) src++;

    // Copy the string to the "front" of the buffer
    for(dest=0; src<len; dest++, src++) 
    {
        String[dest] = String[src];
    }

    // Working backwards, set all trailing spaces to NULL.
    for(dest=len-1; isspace(String[dest]); --dest)
    {
        String[dest] = '\0';
    }
}
于 2010-03-15T22:28:28.947 に答える
1

そのコードにはいくつかの問題があります。スペースのみをチェックします。タブや改行ではありません。文字列の空白以外の部分全体をコピーしています。そして、設定する前に lastc を使用しています。

代替バージョンは次のとおりです(コンパイル済みですが、テストされていません):

char *trim(char *string)
{
    char *start;
    int len = strlen(string);
    int i;

    /* Find the first non whitespace char */
    for (i = 0; i < len; i++) {
        if (! isspace(string[i])) {
            break;
        }
    }

    if (i == len) {
        /* string is all whitespace */
        return NULL;
    }

    start = &string[i];

    /* Remove trailing white space */
    for (i = len; i > 0; i--) {
        if (isspace(string[i])) {
            string[i] = '\0';
        } else {
            break;
        }
    }

    return start;
}
于 2010-03-15T21:57:55.430 に答える
1

いくつかの問題があります:lastc初期化せずに使用できます。たとえば、while ループの代わりに for ループを使用することもできます。さらに、トリム/ストリップ機能は通常、スペース、タブ、および改行を置き換えます。

これは、私がかなり前に書いたポインターを使用したソリューションです。

void trim(char *str)
{
    char *ptr = str;
    while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') ++ptr;

    char *end = ptr;
    while(*end) ++end;

    if(end > ptr)
    {
        for(--end; end >= ptr && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'); --end);
    }

    memmove(str, ptr, end-ptr);
    str[end-ptr] = 0;
} 
于 2010-03-15T22:02:22.740 に答える
0

文字を空白文字 ' ' と比較する代わりに、ctype.h で定義されていると思われる "isspace" 関数を使用します。

于 2010-03-15T21:59:33.897 に答える
0

クリーンについてはわかりませんが、フォローするのは難しいと思います。これを行う必要がある場合、最初は次の 2 つのフェーズで考えます。

  1. 最初から削除する文字数を計算し、残りの文字列 (null ターミネータを含む) を開始アドレスに memmove します。(別の開始ポインターを返すことが許可されている場合は memmove は必要ないかもしれませんが、その場合はメモリーの衛生状態に十分注意する必要があります。)
  2. (新しい) 端からいくつの文字を削除するかを計算し、そこに新しいヌル ターミネータを設定します。

次に、実装しようとしているように見えるワンパスソリューションを詳しく調べるかもしれませんが、速度の問題があった場合に限ります。

ちなみに、isspace()スペースだけをチェックするのではなく、おそらく使用したいでしょう。

于 2010-03-15T22:01:13.893 に答える