- ベストアンサー
C言語 文字列操作 トリム関数とリムーブ関数
- C言語でトリム関数とリムーブ関数を作成しました。改良点はありますでしょうか?
- トリム関数は、文字列の前後にあるスペースを削除する処理を行います。
- リムーブ関数は、指定された文字列を対象の文字列から削除する処理を行います。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
>改良点はありますでしょうか? てか、関数の「型」から、開発途上のものではないのですか?。 Trim() の仕様は、「文字列の先頭と末尾にある空白を削除」で、「文字列中の空白は削除しない」ですか?。 Remove() の仕様は、「削除文字列の先頭1文字のみ削除」ですか?。 +++++++++++++++++++++++++++++++++++++++++++++++ ・この手の処理は、unsigned char がいいと思います。 ・Trim() を「文字列中の空白も《全て》削除」するようにしてみました。 ・Remove() を「対象文字列中に含まれる(複数の)削除文字列を削除」するようにしてみました。 なお、当コミュニティの投稿上の都合(トリム関数?が働いている)から 半角空白を、_ とし、視認のため全角空白(0x8140)を「□(0x81A0)」としてあります。 #include <stdio.h> #include <string.h> #define un_char unsigned char void Trim( un_char *str ) { int iOn; un_char *p = str; while( *p ){ iOn = 0; if( '_' == *p ){ iOn = 1; strcpy( p, p + 1 ); } if( ( 0x81 == *p ) && ( 0xA0 == *( p + 1 ) ) ){ iOn = 1; strcpy( p, p + 2 ); } if( ! iOn ) p++; } } void Remove( un_char *str, un_char *rmv ) { int size; un_char *p; size = strlen( rmv ); while( 1 ){ p = strstr( str, rmv ); if( NULL == p ) break; strcpy( &str[ p - str ], &str[ p - str + size ] ); } } void main( void ) { un_char str[ 128 ] = "___□c_d□_c□d_____ab_□□__□_cd_□_efgcd□□_"; un_char rmv[ 128 ] = "cd"; printf( "トリム前 |%s|\n", str ); Trim( str ); printf( "トリム後 |%s|\n", str ); Remove( str, rmv ); printf( "リムブ後 |%s|\n", str ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
その他の回答 (3)
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
ポインター版ですが、ちょっと使ってみてください。 char *Trim(char *str) { char *t, *remember; int p; remember = t = str; while(p = *str++){ if(p != ' ') *t++ = p; } *t = '\0'; return remember; } char *Remove(char *str, char *rmv) { char *t, *remember; int p; remember = t = str; while(p = *str++){ if(p != *rmv) *t++ = p; } *t = '\0'; return remember; }
補足
ポインタを駆使したらこんなに短くなるんですね。 驚きです。 パッと見では理解できないので、解析してから利用させていただきます。 ありがとうございます。
- tossy2011
- ベストアンサー率17% (3/17)
Trim ・charを1ずつしか扱わないならばstrncpyは使用せず代入でよい ・全角スペースを削除できない Remove ・削除対象が「文字列」だが「文字」を対象とした処理になっている
補足
ありがとうございます。コメントさせていただきます。 >・charを1ずつしか扱わないならばstrncpyは使用せず代入でよい →strncpyは使用しておりません。 ・全角スペースを削除できない →一般的には全角も消せますよね… 想定していませんでした。 >・削除対象が「文字列」だが「文字」を対象とした処理になっている →この処理だと確かに「文字列」でなく「文字」ですね。ご指摘ありがとうございます。
- Tacosan
- ベストアンサー率23% (3656/15482)
それぞれが何をする関数なのか, きちんと言葉で説明すべきでしょう. Trim はまだしも Remove はいくつかの解釈がありえる. あと, なんかいろいろ不思議な感じがする. 例えば Remove の中の strcpy(&(str[p-str]), p + 1); って, strcpy(p, p+1); としてはいけない理由があるとは思えないし c = '\0'; p = strchr(rmv, c); size = p - rmv; なんて strlen の方が常識的だろう. ちなみにこの strcpy は危険かもしれない. 未定義っぽい気がする.
補足
C言語初心者でポインタについては勉強途中で使い方が中途半端かもしれません。恐縮です。 >strcpy(&(str[p-str]), p + 1); >って, >strcpy(p, p+1); >としてはいけない理由があるとは思えないし →調べましたがpでいけますね。 >なんて strlen の方が常識的だろう. →わざとポインタで長さ出してます。「こんな方法もあるのか!」と関心してしまったばっかりに… >ちなみにこの strcpy は危険かもしれない. →この使い方は未定義でいした。別の方法に変更します。
お礼
ありがとうございます。仕様の指摘のみにとどまらず、サンプルまで投稿していただいた点でベストアンサーとさせていただきます。 >なお、当コミュニティの投稿上の都合(トリム関数?が働いている)から →(笑)私もこのソースコードを投稿した際に驚きました。タブが削除されちゃったんで。 参考にさせていただきます。