性格悪い人が優勝

初心者です。みなさまどうか教えてください。(>_<)

文字列置換関数をつくれ
ただし文字列操作系関数はつかうな(str---)。
void replace(char*str, char*before,char*after);

質問者からの補足コメント

  • すみません(>_<)
    strのなかにbeforeがあればafterで置き換える。それぞれ文字列長さは不定で複数あればすべて置換します。

      補足日時:2016/09/21 20:46
  • 何度も補足申し訳ございません。
    とりあえず自分で考えた部分は
    ♯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]続く

      補足日時:2016/09/22 07:33
  • scanf(“%s”, str);
    scanf(“%s”, before);
    scanf(“%s”, after);
    replace(str, before, after);
    printf(“置き換えた文字列%s”, str);
    return 0;
    }

      補足日時:2016/09/22 07:39

A 回答 (6件)

以下のようにしてください。


---------------------------------------------
#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>
    • good
    • 1
この回答へのお礼

わー!!ありがとうございます!!!

さすがです(。>ω<。)助かりました。何度も復習し頑張ります!!

本当にありがとうございました(〃'▽'〃)

お礼日時:2016/09/22 11:14

「何度も復習し頑張ります」の前にすべきことがあるんじゃないかな~.



この問題だと「文字列を置き換える」ことを要求されているんだけど, 「どういう処理をすれば『文字列の置き換え』ができるのか」って考えた? アルゴリズムがわからなかったらプログラムなど書けるはずもないよ.
    • good
    • 0
この回答へのお礼

そうですね。だいぶ考えました。流れはわかっていたのですがそれをプログラム化する力が現在では全く足りなかったのでお力を借りました。

お礼日時:2016/09/23 02:35

念の為、確認しますが、beforeの文字列よりもafterの文字列のほうが大きい場合は、strが破壊される場合があります。


以下のようなケースです。
strの内容が"abXYab"
beforeの内容が"XY"
afterの内容が"ABCD"
のとき、
置き換えた結果は、
"abABCDab"
となりますが、
strのサイズを呼び出し側で
char str[7];
としていた場合、メモリが破壊されます。
strのサイズを呼び出し側で
char str[9];
としていた場合は、メモリは破壊されません。
呼び出し側は、strのサイズをメモリが破壊されない為の十分大きなサイズを確保してある
という前提で良いでしょうか?
いいかえれば、故意にstrを小さなサイズで確保し、replaceを呼び出した場合、メモリ破壊が発生するが、
それはかまわない。
という前提で良いでしょうか。
    • good
    • 1
この回答へのお礼

回答ありがとうございます!

はい。問題文には呼び出し元(main関数)でstrは置き換え後の文字列を十分格納できることが前提とかいてありました。

説明不足で申し訳ございません(>_<)

お礼日時:2016/09/22 10:38

質問文にあるプロトタイプ宣言の通りであれば、実現不可能です。


beforeよりもafterの方が長いとアウトです。
実は次のようなインタフェースではないですか?
void replace(char**str, char*before,char*after);
もしくは、
char * replace(char*str, char*before,char*after);
とか。
    • good
    • 1
この回答へのお礼

回答ありがとうございます(。>ω<。)そうなんですか…問題をみるかぎり上記のようにはなってないのです。。よくわからない問題で申し訳ございません

お礼日時:2016/09/22 07:41

「初心者」だからなんだというのか.



どこまでできて, どこで困っている?
    • good
    • 0
この回答へのお礼

そうですよね、申し訳ございません。。

補足追加させていただきましたがご覧の通りほぼとけておりません。。

お礼日時:2016/09/22 07:43

char*str の仕様がわからない

    • good
    • 1
この回答へのお礼

早速の回答ありがとうございます。
そうですね。。私もわからず申し訳ございません

お礼日時:2016/09/22 07:44

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