文字列をつなぐ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
macka

文字列をつなぐ

#1

投稿記事 by macka » 16年前

はじめまして今私はポインタの勉強をしていて文字列をつなぐ下記のようなプログラムを作ったのですがabc123と表示させたいのに実行するとabcbcとしか表示されません。間違いの指摘をしていただきたいです。お願いします。
#include<stdio.h>
char *ketugou(char *,char *);
int main(void)
{
	char str[10]="abc";
	char ptr[10]="123";
	printf("%s,%s\n",str ,ketugou(str,ptr));
	getchar ();
	return 0;
}
char *ketugou(char *s,char *p)
{
	int i=0;
	while('\0'!=*(s++)){
	while('\0'!=*(p+i)){
		*(p+i)=*(s+i);
		i++;
	}
	}
	*(p+i)='\0';
	return p;

御津凪

Re:文字列をつなぐ

#2

投稿記事 by 御津凪 » 16年前

現在の ketugou 関数は、 p に s を中途半端に代入しています。
具体的に処理を追うと、
・最初の while 文で '\0'!=*(s++) を比較(sは比較後次のポインタ位置へ)。真なのでループ内へ
・次の while 文で '\0'!=*(p+i) を比較。真なのでループ内へ
・*(p+i)=*(s+i);
 i は 0 なので、 p[0] = s[0] と同じ。
  ただし、s は呼ばれた時と違うポインタ位置(一つずれている)なので、s[0] は 'b' 。
・i++;し、次のループへ。
・*(p+i)=*(s+i);
 i は 1 なので、 p[1] = s[1] と同じ。(s[1] は 'c' )
・i++;し、次のループへ。
・*(p+i)=*(s+i);
 i は 2 なので、 p[2] = s[2] と同じ。(s[2] は '\0' )
・i++;し、次の判定で 偽となるため内側の while 文を抜ける。
・外側の while 文で s++ されているが、 i に変化が無いので、内側の while 文にいくことなく
 そのまま while 文を抜け、関数が終了する。
結果、返されるポインタの文字列は "bc" となる。

box

Re:文字列をつなぐ

#3

投稿記事 by box » 16年前

> 	printf("%s,%s\n",str ,ketugou(str,ptr));

ここで何を出力したいのか、正確に教えてください。
abc123と出力させたいのに、と書かれていますが、上記のprintf()の実行では、
2つの文字列をカンマで区切って出力します。
abc123と出力させることは、もともとできません。

Dixq (管理人)

Re:文字列をつなぐ

#4

投稿記事 by Dixq (管理人) » 16年前

こんな感じでどうでしょう。
連結される側のポインタst1を終端まで進め、そこから連結する側の文字列をコピーする。
コピーした文字が終端記号ならそこで終わる。
コピー先の文字列の先頭アドレスを返す

#include<stdio.h>

char *MyStrcat(char *st1, const char *st2){
    char  *p = st1;
    /* st1を終端まで進める */
    while ( *st1 != '\0' ){
        st1++;           
    }
    /* 連結作業 */
    while ( 1 ){
        /* st2をst1の終わりからつなげる */
        *st1 = *st2;
        /* つなげた文字が終端記号なら抜ける */
        if( *st1 == '\0' ){
            break;
        }
        /* ポインタを進める */
        *st1++;
        *st2++;
    }
    return p;
}

int main(void){
    char str[10]="abc";
    char ptr[10]="123";
    printf("%s,%s\n",str ,ptr);
    printf("-> %s\n",MyStrcat(str,ptr));
    getchar ();
    return 0;
}

実行結果

abc,123
-> abc123


上記の関数は以下のようにかいても同じ意味です。

char *MyStrcat(char *st1, const char *st2){
    char  *p = st1;
    while (*st1) st1++;           
    while (*st1++ = *st2++) ;     
    return p;
}
 
 

macka

Re:文字列をつなぐ

#5

投稿記事 by macka » 16年前

皆さんありがとうございます わかりやすく教えていただいたおかげで理解できました

non

Re:文字列をつなぐ

#6

投稿記事 by non » 16年前

本当にもう大丈夫ですか?
管理人さんのプログラムは難しいと思うけど・・・教科書通りじゃないって気がするけど。
なにが、教科書かって・・つっこまないで。


それでは、問題です。下のプログラムは、なぜ、駄目なんでしょうか。
課題1
char *MyStrcat(char *st1, const char *st2){
    char  *p = st1;
    while (*st1++) ;           
    while (*st1++ = *st2++) ;     
    return p;
}
課題2
char *MyStrcat(char *st1, const char *st2){
    char  *p = st1;
    while (*st1) st1++;           
    while (*st2) *str++=*str++;     
    return p;
}

macka

Re:文字列をつなぐ

#7

投稿記事 by macka » 16年前

どちらもループを途中で抜けてしまうからではないですか?

non

Re:文字列をつなぐ

#8

投稿記事 by non » 16年前

課題2にミスがありました。失礼しました。
課題2 

char *MyStrcat(char *st1, const char *st2){
    char  *p = st1;
    while (*st1) st1++;           
    while (*st2) *st1++=*st2++;     
    return p;
}
>途中で抜けてしまうから
回答が、簡単すぎるので、mackaさんがわかっておられるか、ちょっとはかりかねますが、
おわかりなら、OKです。

macka

Re:文字列をつなぐ

#9

投稿記事 by macka » 16年前

親切にありがとうございました。

閉鎖

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