• ベストアンサー

strcat で型が合わない

#include <iostream.h> main(){ char x[15]; for(int i=0;i<15;i++) x[i]=i+49; for(int i=0;i<15;i++){ cout <<x[i]; }; } 9より先の文字化けは考えないとして、 char x[15]; というのは適切ですか? 16個目の要素になる x[15] には、文字列の最後の \0 が入ると思って char x[14]; にしなかったんです。 コンパイルして実行すると 123456789... となるけど、 2桁にしたいんです。半角スペースを使いたいんです。 1 2 3 4 5... のようにしたいんです。 そのように表示する方法は色々あるけど、 文字列の配列でやる場合の方法が知りたいんです。 #include <iostream.h> main(){ char x[15]; char y=" " for(int i=0;i<15;i++){ x[i]=strcat( y,(char)(i+49) ); }; for(int i=0;i<15;i++){ cout <<x[i]; }; } ↑のようなことやってみたけど、型が合わないとかで うまくできませんでした。 strcat とか strncpy は難しいです。 正しいソースを教えてください。

  • A__
  • お礼率59% (194/328)

質問者が選んだベストアンサー

  • ベストアンサー
  • kokucho81
  • ベストアンサー率61% (157/255)
回答No.6

あれ?違うや #include <iostream.h> #include <string.h> #define LENGTH 15 void main(){ char x[LENGTH * 2]=""; char* y=" "; for(char *p=x, i=0; i<LENGTH; i++,p+=2) { *p=(char)(i+49); strcat(p,y); } cout << x; } こうか。

その他の回答 (7)

回答No.8

>main の次の行は char x[14]; の方がいいということですか? 厳密には、「16文字」(0から15の)入るのであれば、\0 が入ると 17文字入ります。なので・・・ char x[17]; でないといけません。 >のソースで、bcc5.5でコンパイルしようとすると >y = malloc(1024); >の行が 'void *' 型は 'char *' 型に変換できない(関数 main() ) >というコンパイルエラーでした。 y = (char *)malloc(1024); ・・・ってかくべきなんですが あれ、私、ぼけてました。この行いりません。

A__
質問者

お礼

コンパイルできなかったけど、情報ありがとうございました。

  • kokucho81
  • ベストアンサー率61% (157/255)
回答No.7

1個配列足りてないから、この手抜きはダメだなこりゃ。

A__
質問者

補足

1 の左にもスペースを入れたかったから少し変えました。 別の話だけど、ここの書き込みで1文字目に半角スペースを 表示するのは難しそうだ。 #include <iostream.h> void main(){ char x[30]=" "; char* y=" "; for(char *p=x+1, i=0; i<15; i++,p+=2) { *p=(char)(i+49); // 数字文字を入れる strcat(p,y); // 数字文字の後ろに半角スペースを付ける } // x[28] は char 64 が入っている。x[29] は半角スペース cout << x; } これより下に書いてあるソースはどれも #include <string.h> というのは無くてもいいみたいでした。 1個配列足りてない というのはどういうことですか? 問題なさそうでしたよ。 教えてくれたソースはとても難しかったから半分ぐらいしか 分からなかったけど、分かるようになりたいと思いました。 ありがとうございます。

  • kokucho81
  • ベストアンサー率61% (157/255)
回答No.5

strcat は使いたい、 今の感じに似せたい、 ぜひ配列も使いたい、 ということであれば、こうかな~。 #include <iostream.h> #include <string.h> #define LENGTH 15 void main(){ char x[LENGTH * 2]=""; char* y=" "; for(int i=0; i<LENGTH; i+=2) { x[i]=(char)(i+49); strcat(x,y); } cout << x; }

  • misoka
  • ベストアンサー率35% (56/160)
回答No.4

エラーの原因をつきとめるところから始めてみましょう。 1 strcatは、文字列を返しますので、x[i]には代入できませんよね?  x[i]はchar*ではなく、charですから、  char*であるstrcatの戻り値を受け取れないというわけです。 2 strcatの引数は文字列ですので、(char)(i+49) を引数にするのは  ムリではないでしょうか? 3 ちょっとしたケアレスミスと思いますが、char y=" ";というのは、  ムリです。(" "には'\0'がついてきます) 4 これもケアレスミスと思いますが、for文のブロックの終わりには、  ;は不要。 単純で分かりよい書き方だとこんな感じになるんじゃないかな? と思います。 --------------------------------- char x[30]; int j = 0; for( int i = 0; i < 15; i++ ) {  x[j] = ( char )( i + 49 );  x[j + 1] = ' ';  j += 2; } x[29] = '\0'; 最後の文は、forループで1バイトずつ出力するなら 要りませんが、基本的にはヌル文字を含む文字列として 扱う方が、間違いがないと思います。 だから、x[29] = '\0' として、出力は(ループせずに) cout << x; とした方がよいでしょう。

A__
質問者

お礼

"文字" と '文字' の違いを知りませんでした。 やっと分かったところです。 for に {} を使った場合に {} の次に ; は不用だということも 今知りました。 質問文に書いた2つめの for は元々 {} は不用だったことも 今気付きました。 教えてくれたソースは理解できました。 最後の x[29] = '\0'; で、出力が cout << x; というふうに簡単になるところが気に入りました。 ありがとうございます。

  • shigatsu
  • ベストアンサー率26% (511/1924)
回答No.3

char 型の変数ならダブルクォートじゃなくてシングルクォートじゃないでしょうか? char y=' '; で、xという配列は15しか要素数が無いので、文字を15個入れたら、 y を入れる隙間は無いですよね? もし入れるとしたら、14増やした29で配列を確保する必要が有ると思います。 それとstrcatだとどんどんyに追加していってしまいますので、領域確保されていないためヘンなところに書き込んじゃいますね。 全て配列でやるのであれば、strcatなどの文字列処理関数は使わないほうがいいですね。それと配列の要素を1つずつ出力するなら最後の \0 も必要ないでしょう。 #define MAXSIZE 29 char x[MAXSIZE]; for(i=0; i<MAXSIZE; ) { x[i++] = ??????; /* 文字を入れる */ x[i++] = ??????; /* スペースを入れる */ } 同じ意味を持つ数値は名前を付けたほうが間違いが無いです。 ??? の部分は考えてください。

  • zonbie
  • ベストアンサー率27% (3/11)
回答No.2

絶対に、x[i] には1文字しか入らないのを理解して下さい。 質問のソースでは、x[i] の中に「半角スペース」と「i+49]と 「\0」を入れようとしてますよね。 すると、 x[0] →「半角スペース」 x[1] →i+49 x[2] →'\0' になってしまうので、ひとつのやり方として 2次元配列を使ってみます。 #include <iostream.h> #include <string.h> void main(){ char x[16][3]; char y[3]; int i; for(i=0;i<15;i++){ strcpy(y," "); x[i][0] = (char)(i+49); x[i][1] = '\0'; strcat( y, &x[i][0]); strcpy(&x[i][0],y); } for(i=0;i<15;i++){ cout << &x[i][0]; } }

回答No.1

まず、char x[15] が定義された場合 x[0]からx[14] までが使用できるようになります。 x[15] は、使えません。 x[i] は char型ですので、1バイトになります。 そして、i は、(宣言されてませんね?)は、int型となりますので 一般的な32bitCPUでは、4バイトになります。 ですので、このようなことがおきます。 char x[15]; for(int i=0;i<15;i++) x[i]=i+49; の場合・・・ i = 14 の場合 x[14] = (char)(14 + 49) x[15] = (char)0 x[16] = (char)0 x[17] = (char)0 ということになります。(注:自動キャスト変換されている場合はなりません) #include <stdio.h> int main(void) { char x[15]; char *y = " "; /* 2文字スペース+\0 */ int i; y = malloc(1024); /* メモリ確保 */ for (i = 0; i < 15; i++) { sprintf(y, "%2c", i + 49); printf("%s", y); } }

A__
質問者

補足

ありがとうございます。 main の次の行は char x[14]; の方がいいということですか? #include <iostream.h> #include <stdio.h> int main(void) { char x[15]; char *y = " "; /* 2文字スペース+\0 */ int i; y = malloc(1024); /* メモリ確保 */ for (i = 0; i < 15; i++) { sprintf(y, "%2c", i + 49); printf("%s", y); } } のソースで、bcc5.5でコンパイルしようとすると y = malloc(1024); の行が 'void *' 型は 'char *' 型に変換できない(関数 main() ) というコンパイルエラーでした。

関連するQ&A

  • strcatの処理方法

    #include <iostream.h> #include <string.h> int main(){char a[]="a";char b[]="b"; char c[]="c"; for(int d=0;d<3;d++){strcat(a,b); strcat(a,c);cout<<a;}} このc言語プログラムの実行結果を、abcbcbc したいのですが、例外処理されます。解決方法お願いします。後、又簡単な連結方法教えてください。

  • strcat(p,y)

    #include <iostream.h> void main(){ char x[29]="abcde"; char* y="~"; for(char *p=x+1, i=0; i<15; i++,p+=2) { *p=(char)(i+49); // x[奇数] に数字文字を入れる strcat(p,y); // 数字文字の後ろにチルダを付ける } cout << x << endl << x[29] << endl << x[30]; } ↓出力結果 ------------------------------------- a1~2~3~4~5~6~7~8~9~:~;~<~=~>~?~ ? ~ ------------------------------------- 1回目に動作する strcat(p,y) の処理を教えてください。 strcat(p,y) の処理をされる前は、 x[0]='a' x[1]='b' x[2]='c' x[3]='d' x[4]='e' ... となっていると思います。 1回目の strcat(p,y) で、x[1]='b' x[2]='~' x[3]='\0' x[4]='e' ... となると思うんだけど、この考えは合っていますか?

  • 下記、プログラム内の「char *」の役割

    C++初心者です。 縦長になってしまいますが、 『 #include <iostream.h> void show(int); void show(double); void show(char *);   ←左記の記述の使い方 int main(void) { show(1); show(0.25); show("文字列"); return 0; } void show(int x) { cout << x << endl; } void show(double y) { cout << y << endl; } void show(char *z) { cout << z << endl; } 』 のプログラムにおいて、「char *」の使い方がいまいち理解できません。 上記プログラムですとエラーが表示されないのですが、下記のプログラムだとエラーが発生します。 『 #include <iostream.h> void show(int); void show(double); void show(char);   //←---------上記と違う行 int main(void) { show(1); show(0.25); show("文字列"); return 0; } void show(int x) { cout << x << endl; } void show(double y) { cout << y << endl; } void show(char z) {  //←---------上記と違う行 cout << z << endl; } 』 なぜ、ポインタ(*)を付けないといけないのか分かりやすく教えていただけましょうか。

  • 自作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は一文字少なく表示されてしまいます。自分ではどこをどう直せばいいかわかりません。よろしくお願いします。

  • 配列の逆順コピー

    for文を使って、配列xの並びを逆順にしたものを配列yにコピーするプログラムを作りたいのですがうまくいきません。どうすればよいでしょうか? #include<iostream.h> int main(void){ int i,j; int x[5]={1,2,3,4,5}; int y[5]; for(i=4;i>=0;i--){ for(j=0;j<5;j++){ x[i]=y[j]; } } for(j=0;j<5;j++) cout<<y[j]<<endl; return 0; }

  • 文字列の処理

    #include <iostream.h> main(){ char x[1]; //ここで あいうえお という5文字を入力 cin >>x; ? } ↑いうえ という文字を cout << で表示するにはどうしたらいいんですか?

  • 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言語では文字のサイズを一度宣言したら、変えられないと思うので、困っています。 どなたかアドバイスをいただけないでしょうか。 よろしくお願いします

  • strcat関数のオーバーフロー回避について

    C言語を勉強中の者です。開発環境はWindows7 Visual Studio 2010です。 2つの文字列を入力し、strcat関数を用いて文字列を結合、出力するプログラム を作成しています。文字列は1つの配列につき最大半角5文字です。 本来であれば、char st1[11];ではなく、char st1[6]; としたかったのですが、char st1[6];とすると、strcat関数を実行した際に バッファオーバーフローによるエラーが出てしまいます。 この様な時に、もっと合理的なコードの書き方があれば教えていただけないでしょうか。 よろしくお願いします。 #include <stdio.h> #include <string.h> void main(void) { char st1[11]; char st2[6]; printf("文字列(5文字以内)"); scanf("%s", st1); printf("文字列(5文字以内)"); scanf("%s", st2); strcat(st1, st2); printf("%s", st1); }

  • アドバイスお願いします

    二つの顔文字を横移動しながら交互に変換したいんですけど 横移動しながら変換できるようにはなったんですけど 一番最初に顔文字が残ってしまい不自然なんですけどどうすれば消えるでしょか?アドバイスお願いします #include<iostream> using namespace std; int main() { int i,k,t; char str[] = "(~~)"; char str2[] = "(<>)"; for(i = 1; i < 10; i++){ cout << " "; for(k = 0; k < i; k++){ cout << " "; } for( t = 0; t < 2000; t++ ) if( i % 2 == 0 ){ cout << str; cout << '\r'; }else{ cout << str2; cout << '\r'; } } cout << "\n"; return 0; }

  • どこがちがうのでしょうか?

    以下の二つのプログラムはユーザーが文字を入力し、80文字以下なら ピリオドを追加して表示するというものです。上はうまくいきますが、下はうまくいきません。なぜでしょうか? #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str);i<79;i++) strcat(str,"."); } printf("%s",str); } #include<stdio.h> #include<string.h> #include<stdlib.h> int main() { char str[80]; int i; printf("文字列を入力してください。\n"); gets(str); if(strlen(str)<80) { for(i=strlen(str)+1;i<79;i++) str[i] = "."; } printf("%s",str); }