掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28588

置換処理について
投稿者---のん(2006/10/27 17:09:10)


OS:WindowsXP
コンパイラ:VisualC++

内容:参考書通り記述し、当然動作はするが処理の部分で理解出来ない箇所があります

/*
#include <stdio.h>
void main(void){

    char* p;
    static char text[]={"サルビアの花"};
    p=text;
    *p='\0';
    printf("%s\n",p+1);
}
*/

#include <stdio.h>
#include <string.h>
char* search();
void replace();

void main(void){
    int k;
    static char text[][128]={"サルビアの花","いつもいつも思ってた","サルビアの花をあなたの部屋の中に","投げ入れたくて","そして君のベッドに","サルビアの紅い花しきつめて","僕は君を死ぬまで抱きしめていようと",""};

    k=0;
    while(text[k][0]!='\0'){
    
        replace(text[k],"サルビア","か す み 草");
        replace(text[k],"紅","白");
        printf("%s\n",text[k]);
        k++;
    }
}

void replace(char *text,char* key,char* rep){


    char buf[128];
    char* p;

    p=search(text,key);

    while(p!=NULL){

    *p='\0';

    strcpy(buf,p+strlen(key));
    strcat(text,rep);
    strcat(text,buf);
    p=search(p+strlen(rep),key);
    }

}
char* search(char *text,char *key){

    int m,n;
    char *p;

    m=strlen(text);
    n=strlen(key)-1;

    for(p=text;p<=text+m-n;p++){
        if(strncmp(p,key,n)==0){
            return p;
        }
    }
    return NULL;
}



strcpy(buf,p+strlen(key));
strcat(text,rep);
strcat(text,buf);


replace関数内で *p='\0' とありますが、
終端文字をpの先頭アドレスに入れているんですよね?

でもこの場合だとsearch関数で照合したサルビアの花のサ部分は2バイト文字。なので1バイト目に終端文字が入って2バイト目は化けますよね?

その状態で,p(終端文字の入っている先頭アドレス)から照合文字列分だけアドレスをずらし、の花 部分をbufにコピーしている、と。

ここで理解出来ないのが、上で述べた"サ"の2バイト目からのコピーになって"の"の1バイト部分が化けるのでは?という事です。

その後の処理もイマイチ・・・
△strcatは\0を上書きして連結だから結果は
'\0''文字化け'"ル""ビ""ア""の""花"→"か""す""み""そ""う"'\0''文字化け'"ル""ビ""ア""の""花" となる?

か""す""み""そ""う""の""花"'\0''文字化け'"ル""ビ""ア""の""花"
となる?
それで\0以降は表示されないので かすみそうの花。・・・合ってますでしょうか?

参考書に詳しい解説がなかったので考えている事が合っているのかどうかと文字化けについてはどうなっているのかを教えてください。
かなりの乱文ですがよろしくお願いします


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:置換処理について 28589 shu 2006/10/27 17:27:15
<子記事> Re:置換処理について 28591 のん 2006/10/27 18:42:19
<子記事> Re:置換処理について 28592 のん 2006/10/27 18:57:29
<子記事> Re:置換処理について 28593 円零 2006/10/27 19:03:00


No.28589

Re:置換処理について
投稿者---shu(2006/10/27 17:27:15)


>かなりの乱文ですがよろしくお願いします

乱文にもほどがある。

読みにくいを越えて、読みにく過ぎる、
読む気が失せた、読めなかった、読まなかった。

適度に改行しないと、なにがなんやらわからない。


この投稿にコメントする

削除パスワード

No.28591

Re:置換処理について
投稿者---のん(2006/10/27 18:42:19)


/*
#include <stdio.h>
void main(void){

    char* p;
    static char text[]={"サルビアの花"};
    p=text;
    *p='\0';
    printf("%s\n",p+1);
}
*/

#include <stdio.h>
#include <string.h>
char* search();
void replace();

void main(void){
    int k;
    static char text[][128]={"サルビアの花",
                            "いつもいつも思ってた",
                            "サルビアの花をあなたの部屋の中に",
                            "投げ入れたくて",
                            "そして君のベッドに",
                            "サルビアの紅い花しきつめて",
                            "僕は君を死ぬまで抱きしめていようと",""};

    k=0;
    while(text[k][0]!='\0'){
    
        replace(text[k],"サルビア","か す み 草");
        replace(text[k],"紅","白");
        printf("%s\n",text[k]);
        k++;
    }
}

void replace(char *text,char* key,char* rep){


    char buf[128];
    char* p;

    p=search(text,key);

    while(p!=NULL){

    *p='\0';

    strcpy(buf,p+strlen(key));
    strcat(text,rep);
    strcat(text,buf);
    p=search(p+strlen(rep),key);
    }

}
char* search(char *text,char *key){

    int m,n;
    char *p;

    m=strlen(text);
    n=strlen(key)-1;

    for(p=text;p<=text+m-n;p++){
        if(strncmp(p,key,n)==0){
            return p;
        }
    }
    return NULL;
}




strcpy(buf,p+strlen(key));
strcat(text,rep);
strcat(text,buf);


replace関数内で *p='\0' とありますが、
終端文字をpの先頭アドレスに入れているんですよね?

でもこの場合だとsearch関数で照合したサルビアの花のサ部分は2バイト文字。
なので1バイト目に終端文字が入って2バイト目は化けますよね?

その状態で,p(終端文字の入っている先頭アドレス)から照合文字列分だけアドレスをずらし、
の花 部分をbufにコピーしている、と。

ここで理解出来ないのが、上で述べた"サ"の2バイト目からのコピーになって
"の"の1バイト部分が化けるのでは?という事です。

その後の処理もイマイチ・・・

△strcatは\0を上書きして連結だから結果は
'\0''文字化け'"ル""ビ""ア""の""花"→
"か""す""み""そ""う"'\0''文字化け'"ル""ビ""ア""の""花" となる?

で
か""す""み""そ""う""の""花"'\0''文字化け'"ル""ビ""ア""の""花"
となる?

それで\0以降は表示されないので かすみそうの花。・・・合ってますでしょうか?

参考書に詳しい解説がなかったので考えている事が合っているのかどうかと
文字化けについてはどうなっているのかを教えてください。
これでどうでしょうか?




この投稿にコメントする

削除パスワード

No.28598

Re:置換処理について
投稿者---shu(2006/10/28 01:02:51)


書きこみ量が多い。
No.28591とNo.28592の違いは?
replace()の機能は?
search()の機能は?
search()は、strstr()で代用可能。
置換前と置換後が同じ領域による混乱。

    len = strlen(key);
    len2 = strlen(rep);
    p = text;

    while (p = strstr(p, key)) {
        strcpy(buf, p + len);
        strcpy(p, rep);
        p += len2;
        strcpy(p, buf);
    }



この投稿にコメントする

削除パスワード

No.28592

Re:置換処理について
投稿者---のん(2006/10/27 18:57:29)


/*
#include <stdio.h>
void main(void){

    char* p;

    static char text[]={"サルビアの花"};

    p=text;
    *p='\0';

    printf("%s\n",p+1);
}
*/

#include <stdio.h>
#include <string.h>

char* search();
void replace();

void main(void){

    int k=0;

    static char text[][128]={"サルビアの花",
                            "いつもいつも思ってた",
                            "サルビアの花をあなたの部屋の中に",
                            "投げ入れたくて",
                            "そして君のベッドに",
                            "サルビアの紅い花しきつめて",
                            "僕は君を死ぬまで抱きしめていようと",""};

    while(text[k][0]!='\0'){

        replace(text[k],"サルビア","か す み 草");
        replace(text[k],"紅","白");

        printf("%s\n",text[k]);
        k++;
    }
}

void replace(char *text,char* key,char* rep){


    char buf[128];
    char* p;

    p=search(text,key);

    while(p!=NULL){

        *p='\0';

        strcpy(buf,p+strlen(key));
        strcat(text,rep);
        strcat(text,buf);

        p=search(p+strlen(rep),key);
    }

}

char* search(char *text,char *key){

    int m,n;
    char *p;

    m=strlen(text);
    n=strlen(key)-1;

    for(p=text;p<=text+m-n;p++){

        if(strncmp(p,key,n)==0){
            return p;
        }
    }
    return NULL;
}




strcpy(buf,p+strlen(key));
strcat(text,rep);
strcat(text,buf);


replace関数内で *p='\0' とありますが、
終端文字をpの先頭アドレスに入れているんですよね?

でもこの場合だとsearch関数で照合したサルビアの花のサ部分は2バイト文字。
なので1バイト目に終端文字が入って2バイト目は化けますよね?

その状態で,p(終端文字の入っている先頭アドレス)から照合文字列分だけアドレスをずらし、
"の花" 部分をbufにコピーしている、と。

ここで理解出来ないのが、上で述べた"サ"の2バイト目からのコピーになって
"の"の1バイト部分が化けるのでは?という事です。

その後の処理もイマイチ・・・

△strcatは\0を上書きして連結だから結果は
'\0''文字化け'"ル""ビ""ア""の""花"→
"か""す""み""そ""う"'\0''文字化け'"ル""ビ""ア""の""花" となる?

で
か""す""み""そ""う""の""花"'\0''文字化け'"ル""ビ""ア""の""花"
となる?

それで\0以降は表示されないので かすみそうの花。・・・合ってますでしょうか?

参考書に詳しい解説がなかったので考えている事が合っているのかどうかと
文字化けについてはどうなっているのかを教えてください。




この投稿にコメントする

削除パスワード

No.28596

Re:置換処理について
投稿者---shu(2006/10/27 22:31:49)


//
//	置換処理
//

#include <stdio.h>
#include <string.h>

int main(void)
{
    static char text[][128] = {
        "サルビアの花",
        "いつもいつも思ってた",
        "サルビアの花をあなたの部屋の中に",
        "投げ入れたくて",
        "そして君のベッドに",
        "サルビアの紅い花しきつめて",
        "僕は君を死ぬまで抱きしめていようと",
        ""
    }, *key = "サルビア", *rep = "か す み 草";
    int len, len2;
    int i, j, k;
    
    //	1行ずつ
    for (i = 0; text[i][0]; i++) {
        puts(text[i]);
    }
    putchar('\n');
    
    //	1文字ずつ
    for (i = 0; text[i][0]; i++) {
        for (j = 0; text[i][j]; j++) {
            putchar(text[i][j]);
        }
        putchar('\n');
    }
    putchar('\n');
    
    //
    len = strlen(key);
    len2 = strlen(rep);
    
    for (i = 0; text[i][0]; i++) {
        for (j = 0; text[i][j];) {
            if (strncmp(&text[i][j], key, len) == 0) {
                for (k = 0; rep[k]; k++) {
                    putchar(rep[k]);
                }
                j += len;
            }
            else {
                putchar(text[i][j]);
                j++;
            }
        }
        putchar('\n');
    }
    putchar('\n');
    
    return 0;
}



この投稿にコメントする

削除パスワード

No.28603

Re:置換処理について
投稿者---shu(2006/10/28 11:14:14)


//
//	おまけ
//

#include <stdio.h>

int main(void)
{
    static const char *text[] = {
        "%sの花",
        "いつもいつも思ってた",
        "%sの花をあなたの部屋の中に",
        "投げ入れたくて",
        "そして君のベッドに",
        "%sの紅い花しきつめて",
        "僕は君を死ぬまで抱きしめていようと",
        NULL
    },
    *flower[] = {
        "サルビア", "かすみ草",
        "ひまわり", "たんぽぽ",
        "梅", "桃", "さくら",
        "菜", "一輪", "高嶺",
        "卯", "貴乃", "若乃",
        "ブーゲンビリア",
        NULL
    };
    int i, j;
    
    //
    for (i = 0; flower[i] != NULL; i++) {
        for (j = 0; text[j] != NULL; j++) {
            printf(text[j], flower[i]);
            putchar('\n');
        }
        getchar();
    }
    
    return 0;
}



この投稿にコメントする

削除パスワード

No.28624

Re:置換処理について
投稿者---のん(2006/10/29 17:36:45)


色んなサンプルコード載せてくれてありがとうございます。
参考にさせて頂きます。


この投稿にコメントする

削除パスワード

No.28593

Re:置換処理について
投稿者---円零(2006/10/27 19:03:00)


>その状態で,p(終端文字の入っている先頭アドレス)から照合文字列分だけアドレスをずらし、の花 部分をbufにコピーしている、と。
>
>ここで理解出来ないのが、上で述べた"サ"の2バイト目からのコピーになって"の"の1バイト部分が化けるのでは?という事です。
いや、「照合文字列分だけアドレスをずらし」たんじゃなかったんですか?
「サルビア」の長さ分、つまり8バイトずらしたんだから"サルビアの花"の8バイト目からのコピーに決まってるでしょう。
どこから「2バイト目」なんてものが出てきたんですか?

>△strcatは\0を上書きして連結だから結果は
>'\0''文字化け'"ル""ビ""ア""の""花"→"か""す""み""そ""う"'\0''文字化け'"ル""ビ""ア""の""花" となる?
strcatは先頭側の文字列の'\0'以降を上書きしながら連結するのであって、挿入するわけではありません。よって、「"サ"の2バイト目」+"ルビアの花"などというものは残されません。
"か す み 草"で完全に上書きされます。


この投稿にコメントする

削除パスワード

No.28594

Re:置換処理について
投稿者---のん(2006/10/27 21:39:04)


'\0''文字化け'"ル""ビ""ア""の""花"
ココカラ +1ズラス  +3 +5 +7 +8(2バイト中1バイト目)

という事で "の花"を抽出してコピーという事か・・・
考えてる内に混乱してしまったようです。

>strcatは先頭側の文字列の'\0'以降を上書きしながら連結

という事は、

△'\0''文字化け'"ル""ビ""ア""の""花"→
'\0'以降全てを対象に上書きして か す み 草 となると。

その後bufを連結して完成、という訳か。

終端文字を文字列の先頭にしてstrcatを使用したのは初めてなのでとても勉強になりました。

返信ありがとうございました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧