ここから本文です

解決済みのQ&A

C言語で、ある文字列から特定の文字列を削除する関数は無いでしょうか "ABCD"から"...

ichimanniさん

C言語で、ある文字列から特定の文字列を削除する関数は無いでしょうか
"ABCD"から"C"を削除し、"ABD"にするとか

  • 質問日時:
    2011/12/26 19:28:52
  • 解決日時:
    2011/12/27 13:33:12
  • 閲覧数:
    2,964
    回答数:
    3

ベストアンサーに選ばれた回答

buynnnmmm1さん

> ichimanniさん

外部ライブラリを使わない場合は自作しないと無いはずです。

高度な文字列操作するには正規表現使ったら楽に書けるのですが、Cから使うのは面倒です。面倒ですが正規表現ライブラリを使えば可能です。

そんな関数作ってみました。
--- ex507.c
#include <stdio.h>
#include <string.h>

void myf(char *s1, char *s2)
{
char *p=s1;

p=strstr(s1,s2);
if( p!=NULL ) {
strcpy(p,p+strlen(s2));
myf( p+1, s2 );
}

}

int main(void)
{
char s1[]="ABCDEFGABCDEFGABCD";
char s0[]="BCD";

myf(s1,s0);
printf("%s\n",s1);

return 0;
}


---

動作確認時アウトプット
AEFGAEFGA


*** 追記1
myf( s1, s2 );

myf( p+1, s2 );
に修正しました。
動作結果は、上の場合については同じです。


*** 追記2
C++でも良いなら、Boostの正規表現ライブラリはCの正規表現ライブラリよりかなり使いやすいです。動作は他の回答されている方法の方がはやいと思います。

--- boost507_1.C
#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;


int main (int argc, char const* argv[])
{
string s1="ABCDEFGABCDEFGABCD"; //元の文字列
string s2="BCD"; // 置き換え文字列
string s3=""; // 置き換え後の文字列
string r;

r=boost::regex_replace( s1, boost::regex(s2), s3 );

cout << r << endl;

return 0;
}


---

動作確認時アウトプット
AEFGAEFGA

よろしくお願い致します。

  • 違反報告
  • 編集日時:2011/12/26 23:16:23
  • 回答日時:2011/12/26 19:45:33

質問した人からのお礼

  • 皆さん。ありがとうございます。
    こちらで教えていただいた関数を使わせていただきました
    標準関数があれば良かったんですが・・・
  • コメント日時:2011/12/27 13:33:12

グレード

ベストアンサー以外の回答

(2件中1〜2件)

並べ替え:回答日時の
新しい順
古い順

 

rhinosugarさん

/*
1226_7_特定の文字列を削除.C
ichimanniさん
質問日時:_2011/12/26_19:28:52
残り時間:_7日間

C言語で、ある文字列から特定の文字列を削除する関数は
無いでしょうか
"ABCD"から"C"を削除し、"ABD"にするとか

>標準関数にはなかったと思います。C言語で自作すると下記の
__一例になります。
__この関数は1度の呼び出しで、最初に見つかった文字列だけ
__削除します。複数あり得るなら繰返して同じ引数で呼び出せば
__あるだけの同じ文字列が全部削除できます。

*/
#include_<stdio.h>
#include_<string.h>

#define___LS1___99____//_s1入力バッファ寸法
#define___LS2___99____//_s2入力バッファ寸法

//_文字列s1中の部分文字列s2を検索、除去する
//_return:_s1;_削除、NULL;_不変(s2なし)
char_*prtialdel(char_*s1,char_*s2){
__char__*p;_//_文字列s1で、残留する文字の旧位置
__char__*q;_//_文字列s2の各文字
__char__*r;_//_s2対応部分を削除後s1構成文字位置

__p_=_strstr(s1,s2);____//_s1中のs2先頭アドレス
__if(p!=NULL){__________//_s1中にs2があれば
____r_=_p;______________//_その先頭→r
____q_=_s2;_____________//_s2の先頭→q
____while(*q!='\0'){____//_qがs2の末尾に達するまで
______p++;______________//_pと
______q++;______________//_qを同時にインクリメント
____}___//_ここでpはs1中のs2部分の直後の位置に居る
____while(*p!='\0'){____//_pがs1の末尾に達するまで
______*r++_=_*p++;______//_s1の中のs2を上書きする
____}_*r_=_'\0';
____return_s1;__//_s1にs2が含まれ、削除した場合s1を返す
__}else{
____//_s1中にs2が完全な形で存在しない場合NULLを返す
____return_NULL;
__}
}
int_main(void){
__char__s1[LS1];__//_s2を探す文字列
__char__s2[LS2];__//_s1の中で探す文字列
__char__*s;_______//_prtialdel()の戻り値
__int___ls1;______//_s1文字列の長さ
__int___proceed=1;//_継続用フラグ

__do{
____//_入力
____printf("s1(<%dch)_>_",LS1);__gets(s1);
____if((ls1=strlen(s1))==0)_break;//_Enterで打ち切り
____printf("s2(<%dch)_>_",ls1);__gets(s2);
____//_検索、削除
____if(s=prtialdel(s1,s2)){
______printf("s1_=_%s\n",s);
____}else{
______printf("s1にはs2が含まれていません\n");
____}
__}while(proceed);
__printf("Normal_End\n");
__return_0;
}
/*_出力
s1(<99ch)_>_ABCDEFGHIJK
s2(<11ch)_>_EFG
s1_=_ABCDHIJK
s1(<99ch)_>_123__456
s2(<8ch)_>_3__4
s1_=_1256
s1(<99ch)_>_xyz
s2(<3ch)_>_x
s1_=_yz
s1(<99ch)_>_abc
s2(<3ch)_>_c
s1_=_ab
s1(<99ch)_>_abcdefg
s2(<7ch)_>_De
s1にはs2が含まれていません
s1(<99ch)_>_abcdefg
s2(<7ch)_>_de
s1_=_abcfg
s1(<99ch)_>
Normal_End
続行するには何かキーを押してください_._._.
*/

qxxrjbfoさん

なさそうな…
STLのstring使えば簡単に実装できそうですけどね
string a;
でaという名前のstringが定義されて
auto index = a.find("abc");
でabcが最初にあらわれる位置(何文字目か)が返ってきます。
これをint型の変数 x にキャスト変換して入れてやり、
eraseという機能を使ってa.erase(x,x+(消したい文字列の文字数))
で、その部分を消してくれます。

参考までに↓
http://www.geocities.jp/ky_webid/cpp/library/001.html
http://www.cppll.jp/cppreference/cppstring.html

Q&Aをキーワードで検索:

総合Q&Aランキング

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。

知恵コレに追加する

閉じる

知恵コレクションをするID/ニックネームを選択し、「追加する」ボタンを押してください。
※知恵コレクションに追加された質問や知恵ノートは選択されたID/ニックネームのMy知恵袋で確認できます。

ほかのID/ニックネームで利用登録する