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

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

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

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

Q&A

解決済

4回答

4624閲覧

文字列をint型配列に格納するとうまく表示できない理由

mashiba3

総合スコア12

C

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

0グッド

0クリップ

投稿2018/03/15 09:00

前提・実現したいこと

文字列の格納と表示

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

最初のprintf関数でstr[0]の文字しか表示されない

該当のソースコード

/*
文字定数はint型なのになぜintの配列ではだめなのか
strの各要素はint型なのになぜstr[6]はchar型で宣言するのか
char型で宣言されたstr[0]などの要素に文字定数を代入するとき、代入する文字定数をchar型へキャストしなくていいのか
*/

#include <stdio.h>

int main(void)
{
int str[6];
int i;

str[0] = 65; str[1] = 'B'; str[2] = 'C'; str[3] = '\0'; str[4] = 'D'; str[5] = 'E'; printf("配列strに文字列\"%s\"が格納されています。\n", str); for (i = 0; i < 6; i++) { printf("str[%d] = %d\n", i, str[i]); } return 0;

}

試したこと

int str[6]をchar str[6]と宣言するとうまく表示された。

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

コンパイラはvisual studio 2017です。

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

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

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

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

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

guest

回答4

0

printfの%sはあくまでも文字列(バイト列)を出力しようとします。

int str[] ={65,'B'以下略

とした場合、とりあえずリトルエンディアンでint=4byteだとすると、
str には バイト単位で書くと、

65,0,0,0,66,0,0,0 以下略 ```というデータが入っています。 最初の0x00を見つけた時点で文字列末とおもいますので、”A"という長さ1の文字列がわたされたものとしてprintfされます。 int str[] ={’A ','B   '、以下略 みたいにしたらもしかして A B C が出力されるかもしれません。 0x00000041というintデータは、バイト列としてみると 0x41,0x00,0x00,0x00だということです(32bitPCでは)。intが64bitの状況では0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00。 このプログラムでABCと表示させたければ、 str[0]=0x434241; とすればそうなるとはおもいます(未確認)。

投稿2018/03/16 04:09

編集2018/03/16 04:12
a_saitoh

総合スコア702

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

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

mashiba3

2018/03/16 09:08

丁寧な回答ありがとうございました。
guest

0

C言語ではint型には実行環境のCPUが扱いやすい自然なサイズが割り当てられています。(32bit CPUでは4Byte、64bitでは8Byteなど)
つまり、charを単独で扱う場合、上位互換のintで扱った方が高速に処理されることが期待できます。
そういうわけで、getchar()など標準ライブラリの関数では引数や返り値がcharで良い場合でもintになっています。

いっぽう文字列の方はスペース優先です。intの配列だと空きスペースが大量に発生して無駄ですね。

また、intの配列を文字列として出力しようとした場合、最初の要素の1Byte目は先頭の1文字、続く空きスペースには0が入っています。C言語では0は文字列の終端なので、先頭1文字しか表示されないことになります。

投稿2018/03/15 09:51

hichon

総合スコア5737

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

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

asm

2018/03/15 09:57

getchar()の場合はEOFの場合もあるので1byteじゃ表現しきれないという事情もあります。
mashiba3

2018/03/15 10:45

"文字列の方はスペース優先です。intの配列だと空きスペースが大量に発生して無駄ですね。 最初の要素の1Byte目は先頭の1文字、続く空きスペースには0が入っています。C言語では0は文字列の終端なので、先頭1文字しか表示されないことになります。" 納得できました。ありがとうございました。
guest

0

ベストアンサー

こんにちは。

文字定数はint型なのになぜintの配列ではだめなのか

printf()関数が%sに対応するパラメータがchar型へのポインタとして処理するからです。
それがchar型でないものを指していてもchar型として扱います。
C言語は言語思想的に型チェックは緩いです。

strの各要素はint型なのになぜstr[6]はchar型で宣言するのか

質問の意味が分かりません。
char型で宣言したらstrの各要素は当然char型です。当たり前ですがint型ではありません。
int型で宣言したらint型ですね。当然char型ではないです。

char型で宣言されたstr[0]などの要素に文字定数を代入するとき、代入する文字定数をchar型へキャストしなくていいのか

C言語規格はint型の値をchar型へ代入することを許しています。
char型で表現できない値を代入した時の動作は未定義の筈です。なので警告を出すコンパイラもありますね。しかし、文字定数ならchar型に入ることが判っているので警告を出さないかも知れません。この辺はコンパイラの実装次第です。

投稿2018/03/15 09:24

Chironian

総合スコア23272

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

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

mashiba3

2018/03/15 09:31

回答ありがとうございました。
guest

0

printfの"%s"はcharの配列に対応するものだからです。
内部では渡されたポインターをchar型の配列としてアクセスするので正しくは出力されません。

フォーマット指定子一覧

投稿2018/03/15 09:07

PineMatsu

総合スコア3579

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

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

mashiba3

2018/03/15 09:32

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問