質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

Q&A

解決済

2回答

4336閲覧

c言語 数字文字列を逆順に表示

kelt22

総合スコア46

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

0グッド

0クリップ

投稿2020/03/11 13:59

前提・実現したいこと

数字の文字列を逆順に表示させたいです。

発生している問題・エラーメッセージ

下記のような実行結果になってしまいます。なぜ要素数を超えた文字が出てくるのか解説していただけると有り難いです。

該当のソースコード

c

1int main(void){ 2 char number1[5]="12345"; 3 char number2; 4 int i; 5 printf("number1:%s\n",number1); 6 for(i=0;i<2;i++){ 7 number2=number1[i]; 8 number1[i]=number1[4-i]; 9 number1[4-i]=number2; 10 } 11 printf("number1:%s\n",number1); 12 return 0; 13} 14実行結果 15number1:12345 16number1:543212

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/03/11 15:53

そもそもなのですが、数字文字列は5桁固定を前提としていますがそれでよろしいのでしょうか。 現状ですと、5以外の桁数だと途中の反転用forループが破綻します。本質問の限りにおいては5桁で良いのでしょうけれど、質問の題にある「数字文字列を逆順に表示」と言う一般化した目的は果たせないです。
guest

回答2

0

ベストアンサー

説明が難しい質問です。環境によっても結果が変わると思います。
printf関数の実行前に、number2 = '9';という一行を追加してみてください。多分、543219のように表示されると思います。つまり、number2に代入した文字が表示されてしまうわけです。原因は、number1の要素数です。5桁の整数だから5文字で足りる、そう思うかもしれません。しかし、printf関数で表示する場合は異なります。printf関数の%s指定は、ヌル文字に出会うまでずっと、(配列のメモリ領域を超えても)文字を表示し続ける仕様になっています。今回は、number1の領域の直後にnumber2の領域があり、そのあとヌル文字が入っていたため、6文字が出力されたのです。
直し方は簡単で、配列の大きさを6文字分にするか、%s指定をやめて、%.5sのように最大文字数を指定すればよいです。

投稿2020/03/11 14:28

編集2020/03/11 14:35
majiponi

総合スコア1720

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rubato6809

2020/03/11 14:51

> number2 = '9';という一行を追加・・・number2に代入した文字が表示され(るだろう) 大胆な仮説と言いたい方もいるでしょうが、私も同じ想像をしています笑。 そして、良い確認手段だと思います。 確認手段なら number1[] と number2 のアドレスを表示してみれば確実でしょう。
kelt22

2020/03/11 16:32

ヌル文字分の要素数を確保するのを忘れていました。ヌル文字分の要素を確保しないとこのような動作になることもあるとわかり勉強になりました。
guest

0

"12345" は、 12345 の後ろに 文字列の終わりを示す文字として '\0' が含まれていて、6文字あります。
char number1[5] = "12345"; では一文字足りません。
char number1[6] = "12345"; 書くこともできますが、

char number1[] = "12345"; 又は、 char * number1 = "12345"; と記述し、
変数の領域の大きさは、コンパイラに決めていただけば良いかと思いますよ。

投稿2020/03/11 14:54

ShinyaAnan

総合スコア241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

majiponi

2020/03/11 14:59

char * number1 = "12345"; やとあかんで。自動変数に文字列のコピーを作らないから、環境によっては読み出し専用の領域を書き換えることになって落ちるで。
otn

2020/03/11 15:03

> char * number1 = "12345"; と記述し、 char number1[] = "12345"; ですね。
ShinyaAnan

2020/03/11 15:05

そうですね。 最初から、気持ち悪かったのです。 char number1 [6]; // 16は想定される最大文字数 + 1 中略 strcpy(number1, "12345"); と記述するべきですね。
thkana

2020/03/11 15:21

> strcpy(number1, "12345"); > と記述するべきですね。 いやいや、そんなことは全然なくて、 char number1[] = "12345"; でも char number1[6] = "12345"; でも全然かまわないです。 問題は char * number1 = "12345"; は、number1の位置から並んでいる文字列を書き換えようという今回のプログラムにおいては「やってはいけないこと」だということです。
rubato6809

2020/03/11 15:49

何がやってはいけないことなのかは諸説ありそうですが、 char number1[5] = "12345";  も number1[] 配列を反転することも、C言語としては許容されていることです。 強いていえば、終端文字を忘れたまま”%s”で表示しようとしたことがマズかった、という説です。
thkana

2020/03/11 15:54

char * number1 = "12345"; で、 number1[0]='5'; はやっちゃいかんでしょう。これに諸説はないと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問