
トリム関数とリムーブ関数を作成してみました。改良点はありますでしょうか?
~~~~以下ソース~~~~
#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;
}
No.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 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
ありがとうございます。仕様の指摘のみにとどまらず、サンプルまで投稿していただいた点でベストアンサーとさせていただきます。
>なお、当コミュニティの投稿上の都合(トリム関数?が働いている)から
→(笑)私もこのソースコードを投稿した際に驚きました。タブが削除されちゃったんで。
参考にさせていただきます。
No.3
- 回答日時:
ポインター版ですが、ちょっと使ってみてください。
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;
}
この回答への補足
ポインタを駆使したらこんなに短くなるんですね。
驚きです。
パッと見では理解できないので、解析してから利用させていただきます。
ありがとうございます。
No.2
- 回答日時:
Trim
・charを1ずつしか扱わないならばstrncpyは使用せず代入でよい
・全角スペースを削除できない
Remove
・削除対象が「文字列」だが「文字」を対象とした処理になっている
この回答への補足
ありがとうございます。コメントさせていただきます。
>・charを1ずつしか扱わないならばstrncpyは使用せず代入でよい
→strncpyは使用しておりません。
・全角スペースを削除できない
→一般的には全角も消せますよね… 想定していませんでした。
>・削除対象が「文字列」だが「文字」を対象とした処理になっている
→この処理だと確かに「文字列」でなく「文字」ですね。ご指摘ありがとうございます。
No.1
- 回答日時:
それぞれが何をする関数なのか, きちんと言葉で説明すべきでしょう. 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 は危険かもしれない.
→この使い方は未定義でいした。別の方法に変更します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# sprintf()の使い方について 1 2022/08/17 16:16
- C言語・C++・C# C言語 少しの疑問 4 2022/11/08 02:48
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
間接参照のレベルが異なっています
-
fgetsなどのときのstdinのバッ...
-
C言語のfor文です。 繰り返しの...
-
文字列から空白を取り除きたい...
-
-'0'の意味について
-
charからLPTSTRへの変換方法
-
C言語の入力した文字を反転させ...
-
c言語でユーザ関数を利用して入...
-
Linuxでフォルダ内全ファイル名...
-
間接操作のレベルとは
-
型変換
-
構造体の各メンバにfor文からア...
-
c言語配列の結合についてです。...
-
TCHAR文字列?の特定部分の数字...
-
DxLibについて質問です
-
'const char *' 型は 'char *' ...
-
c言語でソーベルフィルタが作り...
-
CStringをwchar_tに変換したい
-
ADOレコードセット操作(Forルー...
-
エラーの意味
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
間接参照のレベルが異なっています
-
C言語のfor文です。 繰り返しの...
-
CStringをwchar_tに変換したい
-
テキストデータをそのままバイ...
-
charからLPTSTRへの変換方法
-
atoi( ) の反対をやりたい
-
charでの計算?
-
配列をnビットシフトする
-
c++ 文字列を入力して、一文字...
-
'const char *' 型は 'char *' ...
-
c言語でユーザ関数を利用して入...
-
干支のプログラム
-
switch文で文字を比較すること...
-
char型からのバイト数取得
-
ネットワークにつながっている...
-
getchar()を int でとる理由...
-
間接操作のレベルとは
-
str系関数を使わずに二つの文字...
おすすめ情報