全角スペースを削除

[戻る]
roccy 2002/07/25(木) 00:41:14
・文字列を取得して、
 その文字列の先頭に空白があれば、削除し、
 最後尾から空白があれば、削除して、
 文字列の前後に空白がない状態にする処理
 をしたいと思っています。

・作業環境は
 MFC
 VC++です。

・半角スペースは、削除できましたが、
 全角スペースの削除方法がわかりません。
CString        Wrk;
        Wrk = GetAt(i)[0];  ←ここで行単位で文字列取得
        Wrk.TrimLeft( _T(" \t") );

roccy 2002/07/25(木) 00:49:04
↑の発言は未完成の状態で送信してしまいました。
・文字列を取得して、
 その文字列の先頭に空白があれば、削除し、
 最後尾から空白があれば、削除して、
 文字列の前後に空白がない状態にする処理
 をしたいと思っています。

・作業環境は
 MFC
 VC++です。

・半角スペースは、削除できましたが、
 全角スペースの削除方法がわかりません。
 しかも簡単にできると助かります。

CString Str="  あ  ";
Str.TrimLeft();
Str.TrimRight();

これだけだと、「あ」の前後にある全角スペースが消えません。
どなたかご存知な方教えてください。

yas0302 2002/07/25(木) 01:10:12
全角だけなら。

while( Str.Left(2)==" " )
{
    Str.Delete(0,2);
}
while( Str.Right(2)==" " )
{
    Str.Delete(Str.GetLength()-2,2);
}

半角も取り除く場合は、
TrimLeft()、TrimRight()と
組み合わせてください。

roccy 2002/07/25(木) 01:23:25
yas0302さんありがとうございます。
なるほど、自分が考えていたものよりも、
スマートなやり方です。

しかしながら、全角スペース、半角スペースが交互にくる場合、
複雑な処理になりますよね。

処理としては、
文字列の左側から全角スペースの削除、半角スペースの削除を
空白以外の文字列が見つかるまで繰り返し、
同様に右側からも繰り返すということですよね。


もっと単純な方法というのはないものでしょうか。
贅沢を言ってごめんなさい

yas0302 2002/07/25(木) 09:49:29
これでどうですか。

while( Str.TrimLeft(_T(" \t")),Str.Left(2)==" " )
{
    Str.Delete(0,2);
}
while( Str.TrimRight(_T(" \t")),Str.Right(2)==" " )
{
    Str.Delete(Str.GetLength()-2,2);
}

うま 2002/07/25(木) 09:55:00
むかし、似たようなことをした覚えがあります。
そのときは、MFCはつかってませんでしたので
参考になるかどうかは分りませんが、
そのときのコードは以下のような感じです。

============================================================
BOOL DeleteSpace(const char* str,char * RetrunBuff,int BuffSize)
{    
  BOOL    bRet = FALSE;
  int        leng = strlen(str),cnt = 0,BuffCnt=0;
  char    *Buff;

  if(RetrunBuff == NULL) return FALSE;

  Buff = new char[leng];
  if(Buff == NULL) return FALSE;

  memset(Buff,0,leng);
  while(cnt < leng && str[cnt] != NULL)
  {
    //半角スペース(0x20)
    if((BYTE)str[cnt] == 0x20)
    {
      cnt++;
    }
    //全角スペース(0x8140)
    else if((BYTE)str[cnt] == 0x81 && (BYTE)str[cnt+1] == 0x40)
    {
      cnt+=2;
    }
    else
    {
       Buff[BuffCnt] = str[cnt];
       cnt++;
       BuffCnt++;
     }
  }

  //コピー先のバッファは足りているか?
  if(BuffSize > BuffCnt) 
  {
    strcpy(RetrunBuff,Buff);
    bRet = TRUE;
  }
  delete []Buff;

  return bRet;
}
=======================================
むか〜しに作った関数なので、あまりスマートな
方法ではないかもしれませんが、一応これで
スペースは消えますよ。
これをちょっと改造してCStringの派生クラスを自分で作って
メンバ関数にするもよし、必要な時に
呼び出せるようにグローバルな関数にするもよし
と思います・・・。

お役に立てればよいですが・・・。

dairygoods 2002/07/25(木) 11:01:22
マルチバイトを扱う場合は、
マルチバイト用関数を使った方が1バイトor2バイトの区別を
しなくて良いので素直な作りにできます。

スッキリしてるかどうかは分かりませんが。

unsigned char* trimleft(unsigned char* str)
{
   while (_ismbcspace(_mbsnextc(str))) 
      str = _mbsinc(str);
   return str;
}

unsigned char* trimright(unsigned char* str)
{
   unsigned char* end = _mbschr(str, '\0'); 
   unsigned char* p;
   for (;; end = p) {
      p = _mbsdec(str, end);
      if (!p || !_ismbcspace(_mbsnextc(p)))
         break;
   }
   return end;
}

クラフトマン 2002/07/25(木) 17:17:24
正攻法は皆さんが示されているので、邪道を^^;
まず、『本文中の全角スペースは、半角スペース二つに変わる仕様だ』と言い張る覚悟が必要。
で、
    Wrk.Replace(" ", "  ");
    //            ↑変換されちゃってるかもしれないので説明。
    //             最初のは全角スペースで、二番目は半角スペース2つ
    Wrk.TrimLeft();
    Wrk.TrimRight();
とします。(未確認)

#というか、TrimLeft(LPCTSTR)で、全角スペースを含めて指定すれば、削除できても
#よさそうだが。出来ないのであれば、TrimLeftのバグといっていいかもしれない。
#おおかた、全角スペース先頭バイト(0x81)を取り出したときに、符号拡張で誤認識
#してるとか、そのあたり。

roccy 2002/08/01(木) 12:56:54
[[解決]]
みなさん、ありがとうございます。

一番楽そうなので、yas0302さんの方法ですることに
しました。
こんなに簡単な方法でできるなんて思いませんでした。
ありがとうございました。

古いスレッドには追加発言できません。