• 締切済み

自作strcat

関数strcatを自分で作ってみました。 #include<stdio.h> char *my_strcat(char *s1, char *s2){ int i = 0; int n = 0; while(s1[i] != '\0'){ i++; } while(s2[n] != '\0'){ s1[i] = s2[n]; i++; n++; } s1[i] = '\0'; return s1; } int main(){ char *s1 = "abc"; char *s2 = "vwxyz"; my_strcat(s1, s2); printf("s1:%s s2:%s\n", s1, s2); return 0; } これを実行したところ、s1はちゃんとs1にs2を連結した形で表示されました。しかし、s2は一文字少なく表示されてしまいます。自分ではどこをどう直せばいいかわかりません。よろしくお願いします。

みんなの回答

  • kenji_aki
  • ベストアンサー率50% (29/58)
回答No.5

s1→[0] s2→[4] [0]番地 |0|1|2|3 |4... |a|b|c|\0|... [4]番地 |4|5|6|7|8|9 |A... |v|w|x|y|z|\0|... my_strcat(s1, s2); |0|1|2|3|4|5|6|7|8 |9 |A... |a|b|c|v|w|x|y|z|\0|\0|... |↑s1 |↑s2 文字列定数がどのようにメモリに配置されているのか 環境によって違います。 今回は、たまたま問題なく実行できただけです。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.4

> char *s1 = "abc"; > char *s2 = "vwxyz"; 上記二つは s1 と s2 に「どのような値」が入ってくるのか、 s1とs2が何を指すのかきちんと理解してください。 文字列「定数」がどのようなものなのか考えれば、 何故、これでダメなのか考えればすぐに分かります。

  • chie65535
  • ベストアンサー率43% (8519/19365)
回答No.3

>char *s1 = "abc"; >char *s2 = "vwxyz"; >my_strcat(s1, s2); 問1.この「s1」の後ろに文字列を連結した時、s1の後ろはどうなりますか?以下のA~Cから正しいと思う物を1つ選びなさい(25点) 選択肢 A.何も起きない B.文字列"vwxyz"が書き込まれる C.何かが書き込まれるが、何が書き込まれるか判らない 問2.また、連結前のs1の後ろには、何がありますか?以下のA~Cから正しいと思う物を1つ選びなさい(25点) 選択肢 A.文字列s2を書き込むだけの充分な開き領域がある B.たぶん文字列s2がある C.そこに何があるか判らない 問3.文字列"abc"と"vwxyz"が、下図の図1ようにメモリに配置されていた場合、関数my_strcatを呼び出した後の、メモリ内の状態はどうなりますか?以下のA~Cから正しいと思う物を1つ選びなさい(25点) 図1 'a'←ポインタs1が指すアドレス 'b'←ポインタs1が指すアドレス+1 'c'←ポインタs1が指すアドレス+2 0←ポインタs1が指すアドレス+3 'v'←ポインタs1が指すアドレス+4、ポインタs2が指すアドレス 'w'←ポインタs1が指すアドレス+5、ポインタs2が指すアドレス+1 'x'←ポインタs1が指すアドレス+6、ポインタs2が指すアドレス+2 'y'←ポインタs1が指すアドレス+7、ポインタs2が指すアドレス+3 'z'←ポインタs1が指すアドレス+8、ポインタs2が指すアドレス+4 0←ポインタs1が指すアドレス+9、ポインタs2が指すアドレス+5 選択肢 A. 'a'←ポインタs1が指すアドレス 'b'←ポインタs1が指すアドレス+1 'c' 'v' 'w' 'x' 'y' 'z' 0 'v'←ポインタs2が指すアドレス 'w' 'x' 'y' 'z' 0 B. 'a'←ポインタs1が指すアドレス 'b'←ポインタs1が指すアドレス+1 'c' 'v'←ポインタs2が指すアドレス 'w'←ポインタs2が指すアドレス+1 'x' 'y' 'z' 0 C. 'a'←ポインタs1が指すアドレス 'b'←ポインタs1が指すアドレス+1 'c' 'v' 'w'←ポインタs2が指すアドレス 'x'←ポインタs2が指すアドレス+1 'y' 'z' 0 0 >printf("s1:%s s2:%s\n", s1, s2); 問4.問3の条件で関数my_strcatを呼び出した結果、上記のprintf関数で表示される文字列はどうなりますか?以下のA~Cから正しいと思う物を1つ選びなさい(25点) 選択肢 A.s1:abc s2:vwxyz B.s1:abcvwxyz s2:vwxyz C.s1:abcvwxyz s2:wxyz すべて、正解は「C」です。 これで100点を取れれば、s2がどうして1文字少なく表示されるかが判ります。 そして、何が悪かったのか、どう直せば良いかも判る筈です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

よかったね~, 死ななくって. my_strcat でどこに書き込んでますか?

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

>これを実行したところ、s1はちゃんとs1にs2を連結した形で表示されました。 たまたまです。よく実行できましたね。 strcat() のマニュアルをまずは読みましょう。

関連するQ&A

  • 自作のstrcatが動かない件

    お世話になります。 Wikiペディアに掲載されていたstrcatの実装例(http://ja.wikipedia.org/wiki/Strcat#.E5.AE.9F.E8.A3.85.E4.BE.8B)をそのまま使って、 mystrcatを作ってみましたが、結果が空白になってしまいます。 [ソース] #include <stdio.h> #include <string.h> #include <stdlib.h> char *mystrcat(char *s1, const char *s2) { char *p = s1; while(*s1++); while(*s1++ = *s2++); return p; } void main(){ char *dst; char *p;; char *src1 = "Hello"; char *src2 = "World"; dst = malloc(strlen(src1)+strlen(src2)+1); printf("%s\n",mystrcat(dst,src1)); printf("%s\n",mystrcat(dst,src2)); free(dst); } [実行結果] 空白2行 [期待していた動作] Hello HelloWorld 何が間違っているのか教えていただけると助かります。 標準のstrcatを使うとHelloとHelloWorldが表示されます。 よろしくお願いします。

  • 自作関数を用いた文字の反転

    タイトルのまんまですが入力された文字を反転して表示する方法がわかりません。 #include <stdio.h> char reversecopy(char moji[]) { int i; char reversemoji[51]; for(i = 50; i > 0; i--) { reversemoji[i] = moji[i]; } return reversemoji[50]; } void main(void) { char n[51]; printf("何か文字を入力してください: "); scanf("%s" ,n); reversecopy(n); n[50] = '\0'; printf("%s\n" ,n); return; } ここまでは作ったのですが、表示されるのは反転されていない文字です。どこかおかしい点があったら(絶対あるはずですが)ご指摘いただければ助かります。 よろしくお願いしますm(_ _)m

  • プログラミング(配列と関数の引数)

    a : ABCDE a : ABCDEFGH Len : 8 a : FGHIJ a : FGH a : FGH, c : FGH 上記のように表示されるプログラムを作りたいのですが、なかなかできません。下記のようなプログラムを作ったのですがどこが間違っているのかよくわかりません。分かる方、指摘をお願いします。 #include <stdio.h> void my_strcpy(char s[], char t[]); int my_strlen(char s[]); void my_strcat(char s[], char t[]); int main(){ char a[10]; char b[10] = "ABCDE"; char c[] = "FGH"; int len; my_strcpy(a, b); printf("a : %s\n", a); my_strcat(a, c); printf("a : %s\n", a); len = my_strlen(a); printf("Len : %d\n", len); my_strcpy(a, "FGHIJ"); printf("a : %s\n", a); a[3] = '\0'; printf("a : %s\n", a); if(strcmp(a, c) == 0){ printf("a : %s, c : %s\n", a, c); } int i, s, t; my_strcpy(a, b + 2); printf("a : %s\n", a); void my_strcpy(char s[], char t[]){ for (i = 0; t[i] != '\0'; i++){ s[i] = t[i]; } s[i] = '\0'; } int my_strlen(char s[]){ int i; for (i = 0; s[i] != '\0'; i++); return i; } void my_strcat(char s[], char t[]){ int i, j; for (i = 0; s[i] != '\0'; i++); for (j = 0; t[j] != '\0'; i++, j++){ s[i] = t[j]; } s[i] = '\0'; } }

  • C言語初心者です。 ジャンケンゲーム

    今、授業の課題でジャンケンゲームを作成していますが、なかなかできません。もし、良かったら何処が違うのか教えてください。 // main.c #include <stdio.h> #include <time.h> //#include <time.h> #include "my.h" main(int argc, char* argv[]){ int i; char s[7]; printf("これはジャンケンゲームです。\n"); printf("手を入力します(グー:1 チョキ:2 パー:3)\n"); scanf("%s",&s[7]); srand((unsigned)time(NULL)); printf("%s\n",jyan(dice(3))); if(s == jyan){ printf("あいこです。\n"); }else if(s == 1 && jyan ==2){ printf("あなたの勝ちです。\n"); }else if(s == 2 && jyan == 3){ printf("あなたの勝ちです。\n"); }else if(s == 3 && jyan ==1){ printf("あなたの勝ちです。\n"); }else{ printf("コンピュターの勝ちです。\n"); } } // dice.c #include <time.h> int dice(int n){ srand((unsigned)time(NULL)); return(rand()%n+1); } // jyan.c char *jyan(int n){ static char s[][7]={"グー","チョキ","パー"}; return s[--n]; } // my.h #include <stdio.h> char *jyan(int hand); //int dice(int n); 見づらくて申し訳ありません。4つのファイルに分けて作成しています。上記のプログラムだと自分の手、コンピューターの手がランダムに出てくるのですが判定が出来ませんでした。アドバイス、よろしくお願いします。 長文になってしまい申し訳ありません。

  • 文字を逆転させて表示させるプログラミングなのですが・・・。

    #include<stdio.h> int main() { char moji[80]; char hantai[80]; int i; int j; int n; printf("半角文字列を入力:"); scanf("%s",moji); for(n=0;moji[n]!='\0';n++); for(i=n-1,j=0,i>=0;i++;j--){ hantai[j]=moji[i]; } hantai[j]='\0'; printf("反対から:%s\n",hantai); return 0; } 反対からが表示されません。 考えたのですがわかりません。

  • strcat関数

    学校の課題で strcat関数と全く同じ働きをするmy_strcatを実装せよ という課題がでています。 strcatは char* strcat(char *dest, const char *str) で表され、文字列 strを文字列 dest に合成して 合成された新しい文字列として dest を返します。 例えば、dest = Japan, str = Korea だったら, 関数処理後に、 dest = JapanKorea を戻り値とします。 ********************************************* my_strcat実装について 実装段階で一番の問題になるのが、文字列のサイズです。 とりあえず、私の書いたコードを示します↓ char* my_strcat(char *dest, const char *src) { int i=0; int j=0; while(*dest) { dest++; i++; } while(*src) { *(dest+i) = src[0]; i++; src++; } *(dest+j) = src[0]; //put null at the end of dest return dest; } 試しにdest=Japan,str=Koreaでやってみたのですが、動きませんでした。 原因はdest の文字サイズを無視した無理やりなりな実装だと考えます。 C言語では文字のサイズを一度宣言したら、変えられないと思うので、困っています。 どなたかアドバイスをいただけないでしょうか。 よろしくお願いします

  • 配列について

    初歩的な質問ですいませんが、質問よろしくお願いします。 ◎1----------------------------- #include<stdio.h> int main(void) { char ss[10]="AB"; printf("ss=%s\n",ss); return 0; } ------------------------------------ ◎2-------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss[0]='A'; ss[1]='B'; ss[2]=0; printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎3------------------------------- #include<stdio.h> #include<string.h> int main(void) { char ss[10]; strcpy(ss,"AB"); printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎4------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss="AB"; printf("ss=%s\n",ss); return 0; } ---------------------------------- 以上4つのプログラムで、◎2と◎3は正常に動くと理解できたのですが、何故、◎1は正常に動き、◎4は「'const char [3]' から 'char [10]' に変換できません。」といったようなエラーが出てしまうか分かりません。 教えていただければ嬉しいです。

  • 文字列とポインタの問題です。

    #include<stdio.h> int f(char *s); int main(void){ char*str="nasida Institute of Technology"; int i; i=f(str); printf("%s:%d\n",str,i); return 0; } int f(char *s) { int j=0; while(*s!='\0'){ if(*s=='t'){ j++; } s++; } return j; } このプログラムの答えが3になるんですが、if文のとこの動作がよく分からないので、よろしくお願いします。

  • atoi関数の自作

    C言語でatoi関数を自作したのですが、正確な答えが出てきません 以下にソースを貼るのでどの当たりを直したらよいのかご教授願います。 1~9までの文字列を一つずつ配列に格納して変換する事を目的として作っています。 実行すると桁あふれしたような値が出てきてしまいます #include<stdio.h> #include<stdlib.h> int pow_10(int m) { int i,prod=1; for(i=0;i<m;i++){ prod=prod*10; } return prod; } ascii2int(char number[]){ int i,j,n[10],num; if(!strcmp(number,"")){ printf("Null string\n"); exit(1); } i=0; while(n[i]!='\0'){ n[i]=n[i]-48; i++; } num=0; for(j=0;j<i;j++){ num=num+n[j]*pow_10(i-1-j); } return num; } main(){ char su[10]; for(;;){ printf("Enter an integar:"); gets(su); if(!strcmp("x",su)){ break; } printf("%d\n",ascii2int(su)); } }

  • ポインタにによる値の表現と文字列の表現について

    ◎1------------------------------ #include<stdio.h> int main(void) { char *pt="ABC"; printf("pt=%s\n",pt); char dt[10]="ABCDE"; char *pp; pp=dt; printf("pp=%s\n",pp); return 0; } -------------------------------------- ◎2---------------------------------- #include<stdio.h> int main(void) { char *pt="ABC"; printf("*pt=%s\n",*pt); char dt[10]="ABCDE"; char *pp; pp=dt; printf("*pp=%s\n",*pp); return 0; } ----------------------------------- ◎3--------------------------------------- #include<stdio.h> int main(void) { int ary[5]={111,222,333,444,-1}; int* pt=ary; while(1){ printf("%d ",*pt); ++pt; if(*pt==-1){ break; } } puts(""); return 0; } ----------------------------------------------- 以上3つのプログラムで、◎1はprintfで「*」が付いてなく、正常に実行出来ました。 ◎2はprintfで「*」が付いてなく、エラーは出ませんが、文字列が表示されませんでした。 ◎3は文字列ではなく値ですが、printfで「*」が付いていて正常に実行できます。 これは、値の場合は「*pt」とすることで、ptのアドレスに値を代入しているという事で、「printf("%d ",*pt);」で実行できたということですかね? 文字列の場合は、先頭のアドレスを渡すだけなので、「printf("pt=%s\n",pt);」のようにしてアドレスを参照しないとダメであるということですか? ◎2で「printf("*pt=%s\n",*pt);」としてしまうと、何が起きてしまうのかわかりません。 以上、教えていただけると嬉しいです。

専門家に質問してみよう