C言語関係掲示板

過去ログ

No.289.VBのtrim関数と同じ関数

[戻る] [ホームページ]

No.1734

VB等のtrim関数と同じ関数ありますか?
投稿者---さる(2002/06/18 11:04:43)


いつも参考にさせていただいています。

文字列から空白を除去する処理をしたいのですが
Trim関数と同様な関数がCにはないのでしょうか
初歩的な質問ですがよろしくお願いします

No.1739

Re:VB等のtrim関数と同じ関数ありますか?
投稿者---ともじ(2002/06/18 21:43:09)


こんばんは。

>文字列から空白を除去する処理をしたいのですが
>Trim関数と同様な関数がCにはないのでしょうか

標準関数には空白も含め特定の文字を除去する関数はありませんので、
strtokという標準関数を使って自作なさってはいかがでしょう。
strtokで区切り文字群に空白を指定しますと、空白以外の文字列が
取り出せますので、それを改めてstrcat関数で連結してはいかがでしょう。

No.1740

Re:VB等のtrim関数と同じ関数ありますか?
投稿者---kikk(2002/06/19 01:02:17)


ども。


>標準関数には空白も含め特定の文字を除去する関数はありませんので、
>strtokという標準関数を使って自作なさってはいかがでしょう。
>strtokで区切り文字群に空白を指定しますと、空白以外の文字列が
>取り出せますので、それを改めてstrcat関数で連結してはいかがでしょう。

strtok()だと両端以外の部分に空白が連続して存在した場合に
うまくいかないのでは?
/* 空文字列""は表示されないはず */
char str[]="   foo     bar  ";
char *p;
p=strtok(str," ");
while (p!=NULL) {
  printf("\"%s\"\n", p);
  p=strtok(NULL," ");
}

trimするには地道に、
1. 非空白文字を先頭から探す
2. 非空白文字を最後(strlen()-1)から探す
3. 1と2の結果を使い、strncpy()で格納
(格納先が元と同じ場合を考慮するならmemmove())
4. 最後に\0を付加
という手順を踏むととりあえずはよいかと。
非空白文字を含まない文字列にも対応すれば、なお可。


(Visual)Basicと違い、Cには文字列型はありません。
また、文字列型の代用のcharの配列は勝手に伸び縮み
しませんので、配列のどの部分を使っているか、考える
必要があります。


では。

No.1741

Re:VB等のtrim関数と同じ関数ありますか?
投稿者---かずま(2002/06/19 03:47:52)


> trimするには地道に、
> 1. 非空白文字を先頭から探す
> 2. 非空白文字を最後(strlen()-1)から探す
> 3. 1と2の結果を使い、strncpy()で格納
> (格納先が元と同じ場合を考慮するならmemmove())
> 4. 最後に\0を付加
> という手順を踏むととりあえずはよいかと。
> 非空白文字を含まない文字列にも対応すれば、なお可。

非空白文字を含まない文字列とは、空白文字だけの文字列で、全部削除して
しまっていいということですね。

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

void trim(char *s)
{
    int i, begin, end;

    for (i = 0; isspace((unsigned char)s[i]); i++)
        ;
    begin = end = i;
    while (s[i++] != '\0')
        if (! isspace((unsigned char)s[i-1]))
            end = i;
    s[end] = '\0';
    if (begin != 0)
        memmove(s, s + begin, end - begin + 1); /* or strcpy(s, s+begin); */
}

int main()
{
    char buf[1024];

    while (fgets(buf, sizeof buf, stdin)) {
        trim(buf);
        printf(":%s:\n", buf);
    }
    return 0;
}


No.1750

Re:VB等のtrim関数と同じ関数ありますか?
投稿者---かずま(2002/06/19 19:04:41)


文字列を 1回だけスキャンすることで、trim の機能を実現しようとして、
strlen を使わなかったのですが、やっぱりシンプルなほうが良いようで
次のように改めさせていただきます。
typedef unsigned char uchar;

void trim(char *s)
{
    int i = strlen(s);

    while (--i >= 0 && isspace((uchar)s[i]))
        ;
    s[i+1] = '\0';
    for (i = 0; isspace((uchar)s[i]); i++)
        ;
    if (i != 0)
        strcpy(s, s + i);
}
先に、後ろの空白文字を削除することで、前の空白文字の削除が strcpy で行
えます。規格書では、オーパーラップするオブジェクト間での strcpy は動作
が未定義、となっていますが、普通の実装を考えるなら、この方向のコピーは
大丈夫でしょう。どうしても気持ちが悪いという人は、strcpy の呼び出しを
{ char *t = s + i; while (*s++ = *t++); } に置き換えればよいでしょう。


No.1743

Re:VB等のtrim関数と同じ関数ありますか?
投稿者---ともじ(2002/06/19 09:40:00)


おはようございます。

>strtok()だと両端以外の部分に空白が連続して存在した場合に
>うまくいかないのでは?

trim関数のように空白を除去するというのは、文字列前後の空白だけ
取り除いて、途中の空白は生かすということなのですね。
VBのtrim関数の仕様を調べてから投稿すべきでした。

#管理人がこれでは本当に面目ないです。精進します。

No.1746

Re:VB等のtrim関数と同じ関数ありますか?
投稿者---さる(2002/06/19 12:04:43)


>おはようございます。
>
>>strtok()だと両端以外の部分に空白が連続して存在した場合に
>>うまくいかないのでは?
>
>trim関数のように空白を除去するというのは、文字列前後の空白だけ
>取り除いて、途中の空白は生かすということなのですね。
>VBのtrim関数の仕様を調べてから投稿すべきでした。
>
>#管理人がこれでは本当に面目ないです。精進します。


早速のご返事いただきありがとうございました。
Cにはtrimと同様な関数はないことがわかりました。
(ちょっと不便・・・)
また皆様にアドバイスいただいた中身を参考に考えてみたいと思います。

どうもありがとうございました