書式指定の前にある空白について

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

書式指定の前にある空白について

#1

投稿記事 by tsk » 6年前

初めて投稿させて頂きます。プログラミング初心者です。
この度C言語を勉強しようと思い立ち、「cの絵本」という本を購入し
C言語の学習しようと思いましたが、序盤の所で躓いてしまいました。
printfの書式指定に関する項目(17ページ、特殊な動作を表す文字)の例題に


#include <stdio.h>

int main()
{
   printf(" %8s %8s¥n", "商品A", "商品B");
}
というコードがあり(本当はもっと長いコードですが、この一行だけが理解できません)、
そして実行結果が

    商品A  商品B

でした。
コードの %8sの前に空白があるのが解らないのです。
%8sの、8という数字は桁数の指定するという事はこの本の項目で学んだのですが、
8という数字と、実行結果の「    商品A」と「  商品B」の桁数とも合わないように思います。
ですので、コードの %8sの前に空白が何か関係してるのかなとも考えたのですが、
どうもしっくりきません。
どなたかご回答の程よろしくお願いいたします。

box
記事: 2002
登録日時: 13年前

Re: 書式指定の前にある空白について

#2

投稿記事 by box » 6年前

printf()のまえによけいな「全角」空白を入れるのはお控えください。
コンパイルできません。
さて、おたずねの件ですが、
書式文字列が
" %8s %8s\n"
でもって、"商品A", "商品B"を出力する場合、
・1バイト分空白をあける
・"商品A"を8バイト分の領域に右詰めで出力する。
・1バイト分空白をあける
・"商品B"を8バイト分の領域に右詰めで出力する。
となります。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

かずま

Re: 書式指定の前にある空白について

#3

投稿記事 by かずま » 6年前

コード:

#include <stdio.h>

int main(void)
{
	printf(" [%8s] [%8s]\n",     "abcdef", "ghijkl");
	printf(" [%-8s] [%-8s]\n",   "abcdef", "ghijkl");
	printf(" [%8.8s] [%8.8s]\n", "abcdef", "ghijkl");
	printf(" [%.8s] [%.8s]\n",   "abcdef", "ghijkl");
	printf(" [%8s] [%8s]\n",     "abcdefghi", "jklmnopqr");
	printf(" [%-8s] [%-8s]\n",   "abcdefghi", "jklmnopqr");
	printf(" [%8.8s] [%8.8s]\n", "abcdefghi", "jklmnopqr");
	printf(" [%.8s] [%.8s]\n",   "abcdefghi", "jklmnopqr");
}
実行結果

コード:

 [  abcdef] [  ghijkl]
 [abcdef  ] [ghijkl  ]
 [  abcdef] [  ghijkl]
 [abcdef] [ghijkl]
 [abcdefghi] [jklmnopqr]
 [abcdefghi] [jklmnopqr]
 [abcdefgh] [jklmnopq]
 [abcdefgh] [jklmnopq]
文字列 "abcdef" は終端の '\0' を含めずに 6バイトです。
文字列 "abcdefghi" は終端の '\0' を含めずに 9バイトです。

%8s は文字列の長さが最短で 8バイトになるように、
足りなければ左にスペースを補います。
8バイト以上の場合はスペースを補わず、
文字列をそのまま出力します。

%-8s は文字列の長さが最短で 8バイトになるように、
足りなければ右にスペースを補います。
8バイト以上の場合はスペースを補わず、
文字列をそのまま出力します。

%8.8s の .8 は、文字列が 8バイトを超える場合、
先頭の 8バイトのみを使用します。

%.8s は、最短で 0バイトになるようにしようとするので、
スペースを補いません。

"商品A" は文字コードがシフトJIS の場合、
8f a4 95 69 82 60 の 6バイトなので、
"abcdef" と同様に出力されます。

"商品A" は文字コードが UTF-8 の場合、
e5 95 86 e5 93 81 ef bc a1 の 9バイトなので、
"abcdefghi" と同様に出力されます。

Windows の文字コードは通常シフトJIS です。
Linux の文字コードは通常 UTF-8 です。

質問をするときは、フォーラムルールにあるように
コードタグを使いましょう。
実行結果もコードタグを使って、
スペースが正しく表示されるようにしましょう。

質問をするときは、フォーラムルールにあるように
使っている環境(OS やコンパイラなど)を明記しましょう。
環境によって実行結果が異なることがあるからです。

かずま

Re: 書式指定の前にある空白について

#4

投稿記事 by かずま » 6年前

かずま さんが書きました:
6年前
"商品A" は文字コードが UTF-8 の場合、
e5 95 86 e5 93 81 ef bc a1 の 9バイトなので、
"abcdefghi" と同様に出力されます。
同様といっても、幅(桁数)は違います。
"abcdefghi" は、9文字、9桁、9バイトですが、
"商品A" は、3文字、6桁、9バイトです。

tsk

Re: 書式指定の前にある空白について

#5

投稿記事 by tsk » 6年前

ご返信ありがとうございました。
私が投稿したコードが間違っていたのか、一番重要な、問題の %8s の前にある空白が消えていました。
下にもう一度記載させて頂きます。

自分なりにお答えいただいた内容を調べたのですが、
入門書を読み始めたばかりの私には理解が出来ませんでした。申し訳ありません。


"商品A"は文字列の長さが8バイトを超えないので(1文字2バイトで合計6バイトでしょうか)
%8s 内に収まって、
右詰めで" 商品A"というように左に半角で2バイト分の空白ができると思うのですが、
(全角の日本語を表示しているのでシフトJISコードだと解釈しているのですが、
違っていたらすみません。)

また本の内容の実行結果を見てみると、コードの%8s前の空白が、
実行結果の商品A、商品Bの前の空白が、コードの%8s前の空白よりも間隔が広くなっています。

    商品A  商品B
  ↑ココと  ↑ココ 

ここが一番わからなくて困っております。
なぜ実行結果の商品A、商品B前の空白の間隔が広くなっているのでしょうか?

実際の本の内容のurlがコチラになります。

http://u0u1.net/J0Bg

よろしくお願いいたします。

コード:

 
 #include <stdio.h>

int main()
{
    printf("    %8s   %8s¥n", "商品A", "商品B");
}
環境 os Windows10

tsk

Re: 書式指定の前にある空白について

#6

投稿記事 by tsk » 6年前

すみません、解決いたしました。
" %8s %8s¥n"の前の空白が実行後で間隔が広がっていたのは、
商品A、商品Bは全角文字3文字で、半角6文字分のスペースを使い、
残りの半角2文字分の半角スペースと、
%8の前のスペースが半角スペースとして出力されていたためだと思われます。

回答して頂き誠にありがとうございました。

Math

Re: 書式指定の前にある空白について

#7

投稿記事 by Math » 6年前

そのようですね

OS Windows10,Embarcadero C++ コンパイラ(BorlandC++ Compiler 5.5の後継)で実行した結果です。

b.bat
type c1.c

bcc32c c1.c

c1.exe

pause
http://www2.koyoen.birdview.co.jp/~abcxyz/や.PNG

これをエディターにコピーして 半角空白を表示すると

http://www2.koyoen.birdview.co.jp/~abcxyz/よ.png

プログラムは半角空白、全角空白を表示させることが重要です。

tsk

Re: 書式指定の前にある空白について

#8

投稿記事 by tsk » 6年前

なんとわざわざ画像まで貼り付けてくださり、
非常にわかりやすく、頭の中が整理されました!
誠にありがとうございました!
参考にさせて頂きます!

返信

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