

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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語 int temp = 0; if(isdigit(arr[i])){ temp=arr[i] 2 2022/03/27 01:44
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# 【C言語】全角文字の配列を、全角のまま1文字ずつ出力する方法 4 2023/05/09 15:08
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
文字列から空白を取り除きたい...
-
fgetsなどのときのstdinのバッ...
-
charからLPTSTRへの変換方法
-
配列をnビットシフトする
-
CStringをwchar_tに変換したい
-
charでの計算?
-
テキストデータをそのままバイ...
-
【C言語】テキストファイル内の...
-
間接参照のレベルが異なっています
-
<>で囲まれた文字列を文字列の...
-
Linuxでフォルダ内全ファイル名...
-
英単語をアルファベット順に
-
switch文で文字を比較すること...
-
atoi( ) の反対をやりたい
-
コマンドラインに入力されてい...
-
C言語のfor文です。 繰り返しの...
-
至急!C言語文字列置換
-
間接操作のレベルとは
-
getchar()を int でとる理由...
-
PROCのコンパイルエラーの取り...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
文字列から空白を取り除きたい...
-
CStringをwchar_tに変換したい
-
charからLPTSTRへの変換方法
-
テキストデータをそのままバイ...
-
c++ 文字列を入力して、一文字...
-
'const char *' 型は 'char *' ...
-
間接操作のレベルとは
-
WORDをcharに変換する方法
-
strncpyと_tcsncpy_sのヌルの扱...
-
型変換
-
配列をnビットシフトする
-
atoi( ) の反対をやりたい
-
Win32APIでのエディットボック...
-
間接参照のレベルが異なっています
-
c言語配列の結合についてです。...
-
【C言語】テキストファイル内の...
-
double型の値をchar配列に変換...
-
switch文で文字を比較すること...
-
C言語のfor文です。 繰り返しの...
おすすめ情報
すみません(>_<)
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;
}