No.5ベストアンサー
- 回答日時:
以下のようにしてください。
---------------------------------------------
#include <stdio.h>
#include <string.h>
//自前の文字列操作関数
//strのlengthを返す(自前のstrlen)
int mystrlen(char *str){
int i = 0;
while(*str){
i++;
str++;
}
return i;
}
//メモリの比較を行う(自前のmemcmp)
int mymemcmp(void *str1,void *str2,int len){
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
int i = len;
if (len == 0) return 0;
while(*s1 == *s2){
i--;
if (i == 0) return 0;
s1++;
s2++;
}
return (*s1 - *s2);
}
//メモリのコピー(str1<--str2)(自前のmemmove)
void mymemmove(void *str1,void *str2,int len)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
if (s1 < s2){
while(len > 0){
len--;
//前からコピー
*s1++ = *s2++;
}
}else{
while(len > 0){
len--;
//後ろからコピー
*(s1+len) = *(s2+len);
}
}
return;
}
//メモリのコピー(str1<--str2)(自前のmemcpy)
void mymemcpy(void *str1,void *str2,int len)
{
unsigned char *s1 = (unsigned char*)str1;
unsigned char *s2 = (unsigned char*)str2;
while(len > 0){
len--;
*s1++ = *s2++;
}
return;
}
//課題の関数
//myxxxxのmyをとり実際に存在するxxxxを呼び出しても同じ結果が得られる筈
//例 mystrlen--->strlen
//例 mymemcmp--->memcmp
//例 mymemcpy--->memcpy
//例 mymemmome--->memmove
void replace(char *str,char *before,char *after)
{
int slen = mystrlen(str);
int blen = mystrlen(before);
int alen = mystrlen(after);
int len;
char *s = str;
char *from;
char *to;
/*
if (blen < alen){
printf("afterの長さ>beforeの長さの為処理を中止します\n");
return;
}*/
while(*s){
//str中にbeforeがあるかチェックする
if (mymemcmp(s,before,blen) == 0){
//存在する場合
//beforeの後の文字列の移動
from = s + blen;
to = s + alen;
len = mystrlen(from);
mymemmove(to,from,len);
//終端に\0を設定
*(to+len) = '\0';
//文字列の置換
mymemcpy(s,after,alen); //mymemmoveを使用しても問題ない
//次は置換された文字列の次から処理する
s = to;
continue;
}
s++;
}
}
//replace呼び出し前後のstr,bofore,afterの内容を表示
void test(char *str, char *before,char *after)
{
printf("実行前\n");
printf("<%s> <%s> <%s>\n",str,before,after);
replace(str,before,after);
printf("実行後\n");
printf("<%s> <%s> <%s>\n",str,before,after);
}
int main(void)
{
char str[256];
strcpy(str,"abcXXefgXXxyzXX");
test(str,"XX","YYY");
strcpy(str,"abcXYZefgXYZxyzXYZ");
test(str,"XYZ","AB");
strcpy(str,"abcXXXXXX");
test(str,"XX","ABCD");
return 0;
}
----------------------------------------------
以下、実行結果です。
実行前
<abcXXefgXXxyzXX> <XX> <YYY>
実行後
<abcYYYefgYYYxyzYYY> <XX> <YYY>
実行前
<abcXYZefgXYZxyzXYZ> <XYZ> <AB>
実行後
<abcABefgABxyzAB> <XYZ> <AB>
実行前
<abcXXXXXX> <XX> <ABCD>
実行後
<abcABCDABCDABCD> <XX> <ABCD>
わー!!ありがとうございます!!!
さすがです(。>ω<。)助かりました。何度も復習し頑張ります!!
本当にありがとうございました(〃'▽'〃)
No.4
- 回答日時:
念の為、確認しますが、beforeの文字列よりもafterの文字列のほうが大きい場合は、strが破壊される場合があります。
以下のようなケースです。
strの内容が"abXYab"
beforeの内容が"XY"
afterの内容が"ABCD"
のとき、
置き換えた結果は、
"abABCDab"
となりますが、
strのサイズを呼び出し側で
char str[7];
としていた場合、メモリが破壊されます。
strのサイズを呼び出し側で
char str[9];
としていた場合は、メモリは破壊されません。
呼び出し側は、strのサイズをメモリが破壊されない為の十分大きなサイズを確保してある
という前提で良いでしょうか?
いいかえれば、故意にstrを小さなサイズで確保し、replaceを呼び出した場合、メモリ破壊が発生するが、
それはかまわない。
という前提で良いでしょうか。
回答ありがとうございます!
はい。問題文には呼び出し元(main関数)でstrは置き換え後の文字列を十分格納できることが前提とかいてありました。
説明不足で申し訳ございません(>_<)
No.3
- 回答日時:
質問文にあるプロトタイプ宣言の通りであれば、実現不可能です。
beforeよりもafterの方が長いとアウトです。
実は次のようなインタフェースではないですか?
void replace(char**str, char*before,char*after);
もしくは、
char * replace(char*str, char*before,char*after);
とか。
回答ありがとうございます(。>ω<。)そうなんですか…問題をみるかぎり上記のようにはなってないのです。。よくわからない問題で申し訳ございません
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
charからLPTSTRへの変換方法
-
C言語の入力した文字を反転させ...
-
charでの計算?
-
バイナリファイルをコピーする...
-
型変換
-
絶対パスからのファイル名の切...
-
Linuxでフォルダ内全ファイル名...
-
CStringをwchar_tに変換したい
-
RGBをCMYKに変換するプログラム
-
コマンドラインに入力されてい...
-
文字列から空白を取り除きたい...
-
分割した単語の頻出頻度を表示...
-
【C言語】文字型と整数型の違い
-
C言語 バイナリファイルをfloa...
-
プログラムを作成(c言語)
-
enumの記述について。
-
-'0'の意味について
-
TCHAR文字列?の特定部分の数字...
-
recvfrom関数の戻り値がおかし...
-
atoi( ) の反対をやりたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
CStringをwchar_tに変換したい
-
charでの計算?
-
文字列から空白を取り除きたい...
-
charからLPTSTRへの変換方法
-
'const char *' 型は 'char *' ...
-
テキストデータをそのままバイ...
-
配列をnビットシフトする
-
半角カナ→16進
-
double型の値をchar配列に変換...
-
sprintfに同じ変数は使えるか
-
ファイル名である文字列からbas...
-
ネットワークにつながっている...
-
ftoa の作り方
-
間接操作のレベルとは
-
型変換
-
C言語です
-
C言語のfor文です。 繰り返しの...
-
Win32APIでのエディットボック...
-
【C言語】文字型と整数型の違い
おすすめ情報
すみません(>_<)
strのなかにbeforeがあればafterで置き換える。それぞれ文字列長さは不定で複数あればすべて置換します。
何度も補足申し訳ございません。
とりあえず自分で考えた部分は
♯include〈stdio.h〉
void replace(char*str, char*before, char*after)
{
int i, j, y;
for(i=0; str[i]!=′¥0′; i++){
for(j=0; before[j]!=′¥0′; j++){
if(str[i+j]==before[j]){
y==1;
}
}
}
int main()
{ char str[3000];char*before[1000];char*after[1000]続く
scanf(“%s”, str);
scanf(“%s”, before);
scanf(“%s”, after);
replace(str, before, after);
printf(“置き換えた文字列%s”, str);
return 0;
}