アプリ版:「スタンプのみでお礼する」機能のリリースについて

トリム関数とリムーブ関数を作成してみました。改良点はありますでしょうか?

~~~~以下ソース~~~~

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

char *Trim(char *str);
char *Remove(char *str, char *rmv);
void main(void)
{
 char str[10], rmv[10], *p;
 int c;

 /* " abcd "をトリムする */
 strcpy(str, " abcd ");
 printf("トリム前 |%s|\n", str);
 p = Trim(str);
 printf("トリム後 |%s|\n", str);


 /* 指定文字列を削除する */
 printf("削除する文字列を入力してください :");
 scanf("%s", rmv);
 Remove(str, rmv);
 printf("削除後 |%s|\n", str);
 exit(0);

}
char *Trim(char *str)
{
 char space[] = " ";
 char null[] = "";
 int index = 0;
 while(1){
  if(strcmp(&(str[index]), null) == 0){
   index--;
   if(strncmp(&(str[index]), space, 1) == 0){
    strcpy(&(str[index]), &(str[index]) + 1);
   }else{
    break;
   }
  }else{
   if(strncmp(&(str[index]), space, 1) == 0 && index == 0){
    strcpy(&(str[index]), &(str[index]) + 1);
   }else{
    index++;
   }
  }
 }
 return str;
}

char *Remove(char *str, char *rmv)
{
 int c, size, i;
 char *p;
 c = '\0';
 p = strchr(rmv, c);
 size = p - rmv;

 for(i = 0; i < size; i++){
  c = (int)rmv[i];
  p = strchr(str, c);
  if (p != NULL) {
   strcpy(&(str[p-str]), p + 1);
  }
  else{
   printf("""%c""は見つかりませんでした\n", c);
  }
 }
 return str;
}

A 回答 (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 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
    • good
    • 0
この回答へのお礼

ありがとうございます。仕様の指摘のみにとどまらず、サンプルまで投稿していただいた点でベストアンサーとさせていただきます。

>なお、当コミュニティの投稿上の都合(トリム関数?が働いている)から
→(笑)私もこのソースコードを投稿した際に驚きました。タブが削除されちゃったんで。

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

お礼日時:2011/01/30 18:04

ポインター版ですが、ちょっと使ってみてください。









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;
}

この回答への補足

ポインタを駆使したらこんなに短くなるんですね。
驚きです。
パッと見では理解できないので、解析してから利用させていただきます。
ありがとうございます。

補足日時:2011/01/30 18:06
    • good
    • 0

Trim


・charを1ずつしか扱わないならばstrncpyは使用せず代入でよい
・全角スペースを削除できない

Remove
・削除対象が「文字列」だが「文字」を対象とした処理になっている

この回答への補足

ありがとうございます。コメントさせていただきます。
>・charを1ずつしか扱わないならばstrncpyは使用せず代入でよい
→strncpyは使用しておりません。
・全角スペースを削除できない
→一般的には全角も消せますよね… 想定していませんでした。
>・削除対象が「文字列」だが「文字」を対象とした処理になっている
→この処理だと確かに「文字列」でなく「文字」ですね。ご指摘ありがとうございます。

補足日時:2011/01/30 17:55
    • good
    • 0

それぞれが何をする関数なのか, きちんと言葉で説明すべきでしょう. 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 は危険かもしれない.
→この使い方は未定義でいした。別の方法に変更します。

補足日時:2011/01/30 17:51
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!