strcatの自作に関する質問

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たかし
記事: 48
登録日時: 11年前

strcatの自作に関する質問

#1

投稿記事 by たかし » 11年前

2つの文字列を連結させるstrcat関数を自分で作ってみたのですが、str1とstr2を出力すると

a=ello
b=ByebyeHello

と出力されてしまい、str1の最初の文字が消えていました。
以下が私の作ったプログラムです。

コード:

#include <stdio.h>

char *mystrcat1(char *str1, const char *str2){
	

	while(*str1!='\0'){
		str1++;
	}

	
	while(*str2!='\0'){
		*str1=*str2;
		str1++;
		str2++;
	}

	*str1=0;
	
	return str1;

}

int main (void){
	
	char a[] ="Hello";
	char b[] ="Byebye";
	
	mystrcat1(b,a);
	
	printf("a=%s\n",a);
	printf("b=%s\n",b);
	
	return 0;
}
簡単にプログラムの説明をすると、まずchar型の文字列を2つ受け取り、while文でstr1のポインタを最後まで進めます。
そして次に、while文でstr2の文字がなくなるまでstr1の後ろからstr2の文字を終端までコピーする。
最後にstr1にNULL文字を入れてstr1を返す。
というものです。

何故配列a="Hello"の最初の文字Hはきえてしまったのでしょうか?
よろしくおねがいします。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: strcatの自作に関する質問

#2

投稿記事 by みけCAT » 11年前

Ideoneで実行したところ、正しく

コード:

a=Hello
b=ByebyeHello
と表示されます。
http://ideone.com/VegLsg

あなたが使用している環境(OS、コンパイラなど)を教えてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

fresh_homepie

Re: strcatの自作に関する質問

#3

投稿記事 by fresh_homepie » 11年前

mystrcat1 の代わりに strcat を使っても同じことが起こると思いますが、char配列 b の範囲を超えて書き込んでいるためです(バッファオーバーフロー)。メモリ上で配列aが配列bの後ろのアドレスに配置されているために上書きされてしまっているのでしょう。

この例ではchar配列bは7バイト分(文字数+null文字分)しかありません。あらかじめ十分な領域を確保する必要があります。

box
記事: 2002
登録日時: 13年前

Re: strcatの自作に関する質問

#4

投稿記事 by box » 11年前

コード:

#include <stdio.h>
 
char *mystrcat1(char *str1, const char *str2)
{
    while (*str1 != '\0') {
        str1++;
    }
    while (*str2 != '\0') {
        *str1 = *str2;
        str1++;
        str2++;
    }
    *str1 = '\0';
    return str1;
}
 
int main(void)
{
    char a[] = "Hello";
    char b[] = "Byebye";
    
    mystrcat1(b, a);
    printf("a=%p %s\n", a, a);
    printf("b=%p %s\n", b, b);
    return 0;
}
こんな風に、a[]とb[]のアドレスも出力してみると、2つの配列をメモリー上で
どのように割り当ててあるかを体感できるかもしれません。

今回の場合、b[]の大きさは、結合後の文字列である"ByebyeHello"を
格納できるに足るものでなくてはなりません。最後の'\0'の分も忘れないように。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

たかし
記事: 48
登録日時: 11年前

Re: strcatの自作に関する質問

#5

投稿記事 by たかし » 11年前

皆さん回答ありがとうございます。
みけCAT様、すみません。
コンパイラとOSを書き忘れていました。

OS:windows7
コンパイルと実行に使っているソフト:Cygwin

という環境になっております。

領域が足りないとのご指摘がありましたのでいかのようなものに書き直したらちゃんと出力されました。

コード:

#include <stdio.h>
 
char *mystrcat1(char *str1, const char *str2){
    
 
    while(*str1!='\0'){
        str1++;
    }
 
    
    while(*str2!='\0'){
        *str1=*str2;
        str1++;
        str2++;
    }
 
    *str1=0;
    
    return str1;
 
}
 
int main (void){
    
    char a[100] ="Hello";
    char b[100] ="Byebye";
    
    mystrcat1(b,a);
    
    printf("a=%s\n",a);
    printf("b=%s\n",b);
    
    return 0;
}
また、box様が、a[]b[]のアドレスを出力するよう西田ものを実行したら次のように出力されました。

a=0x28ac4e ello
b=0x28ac47 ByebyeHello

これをみるとたしかにfresh_homepie様がおっしゃられたように配列aが配列bの後ろのアドレスに配置されていることがよくわかりました。

これで、問題は解決できました。
皆様ありがとうございました。
また質問することがあると思いますが、そのときはまたよろしくお願いします。

閉鎖

“C言語何でも質問掲示板” へ戻る