5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

画面に文字を表示する

Last updated at Posted at 2020-03-01

#println!

こんな感じで画面に文字を表示できます。

fn main(){
    println!("画面に出力する文字列");
}

画面表示に関わっているのは以下のコードです。
println!は文字列をコンソール(黒い文字だけの画面)に出力して、その後改行します。

println!("画面に出力する文字列");

Rustでは文字列はダブルクォーテーション"で囲います。ダブルクォーテーションで囲めばそれは文字列として認識され、内容はRustの構文として認識されません。

##プレースホルダ
数値などを表示したい場合はプレースホルダを使います。

fn main(){
    //{}がプレースホルダ。文字列の後にカンマで区切って数値などのデータを書く。
    println!("3 * 4 + 2 = {}",3 * 4 + 2);
}
//実行結果:3 * 4 + 2 = 14

カンマ , の後に書いた数値がプレースホルダの位置に挿入されています。

##書式の指定
format!マクロやprint! println!等のマクロはプレースホルダの中({}の間)に書式を書くと、書式を指定することが出来ます。
plintln!マクロのフォーマット機能はstd::fmtのrustdocで詳細を確認できます。
フォーマット文字列は以下の構文で記述します。

format_string := <text> [ maybe-format <text> ] *
maybe-format := '{' '{' | '}' '}' | <format>
format := '{' [ argument ] [ ':' format_spec ] '}'
argument := integer | identifier

format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
fill := character
align := '<' | '^' | '>'
sign := '+' | '-'
width := count
precision := count | '*'
type := identifier | '?' | ''
count := parameter | integer
parameter := argument '$'

これはたぶんBNFでしょう。
:=の右側の通りに記号を並べると左辺の記号として認識されます。
|は記号の並びに複数のパターンがあることを表します。|を区切りとしてどれか一つが左辺の記号として認識されます。
書式を指定しているのはformat_spec(空行の次にある最も長い行)です。
format_spec := [[fill]align][sign]['#']['0'][width]['.' precision][type]
たくさんのオプションが用意されています。順にみていきます。

##[[fill]align] - アライメントと空白を埋める文字の指定
右寄せ・中央・左寄せの指定と、空白を埋める文字を指定します。
位置を指定する場合は文字列の最小幅である[width]の指定もセットになると思います。
以下は5桁、空白を-で埋めるの書式です。5桁以上の場合はすべての桁が表示されます。
後述しますが、数値の場合の0埋めは[fill]で行うと符号やプレフィックスまで移動するので[`0`]のほうが適しています。

fn main(){
    println!("「{:->5}」", 3); // 「----3」
    println!("「{:-^5}」", 3); // 「--3--」
    println!("「{:-<5}」", 3); // 「3----」
    println!("「{:->5}」", 1234567); // 「1234567」
    println!("「{:-^5}」", 1234567); // 「1234567」
    println!("「{:-<5}」", 1234567); // 「1234567」
}

##[sign] - 符号+を省略せずに表示する
符号を表示できます。
しかし、-は現在(2020/3/7)使われていないようです。
数値がマイナスの値であれば-がつくのであまり問題にはならないでしょう。
[sign][width]を組み合わせる場合は符号の位置に気を付けてください。

fn main(){
    println!("「{:+}」", 123); // 「+123」 「+」の表示を強制する
    println!("「{:+}」", -123); // 「-123」 マイナスの時はちゃんと「-」がつきます
    println!("「{:0>+7}」",123); // 「000+123」 テキスト処理的なゼロ埋め
    println!("「{:+07}」", 123); // 「+000123」 数学的?なゼロ埋めはwidthの前に0を書く
}

##[#] - プレフィックス・改行・インデントを整える
[type]と併用して使います。プレフィックスを付けたり、改行やインデントを入れたりする機能です。
[`#`]に対応していない[type]もあります。
Rustdocに一覧が記載されています。

#? - プリティプリント(改行やインデントなどで形を整えた状態)のデバッグフォーマット
#x - 0xで始まる16進数表示 小文字
#X - 0xで始まる16進数表示 大文字
#b - 0bで始まる2進数表示
#o - 0oで始まる8進数表示

これらの他にも以下の記載が使用できました。2進数、8進数はダメでした。

#x? - プリティプリントのデバッグフォーマットで数値が16進数表示 小文字
#X? - プリティプリントのデバッグフォーマットで数値が16進数表示 大文字

####?
デバッグフォーマットといいます。
データの構造と値を文字列に変換することが出来ます。

#[derive(Debug)]    // これを直前に書くとデバッグフォーマットが使えるようになる
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let origin = Point { x: 123, y: 456 };
    println!("The origin is: {:?}", origin);    // ただのデバッグフォーマット
    println!("The origin is: {:x?}", origin);   // デバッグフォーマットで、数値が16進数表示(小文字)
    println!("The origin is: {:#?}", origin);   // 改行とインデント付きの(プリティプリントの)デバッグフォーマット
    println!("The origin is: {:#X?}", origin);  // プリティプリントのデバッグフォーマットで、数値が16進数表示(大文字)
}

実行結果

The origin is: Point { x: 123, y: 456 }
The origin is: Point { x: 7b, y: 1c8 }
The origin is: Point {
    x: 123,
    y: 456,
}
The origin is: Point {
    x: 0x7B,
    y: 0x1C8,
}

####x,#X,#b,#o
〇〇進数表示でプレフィックスがつきます。

fn main() {
    println!("「{:#x}」", 123); // 「0x7b」
    println!("「{:#X}」", 123); // 「0x7B」
    println!("「{:#b}」", 123); // 「0b1111011」
    println!("「{:#o}」", 123); // 「0o173」
}

##['0'][width] - 最小幅の指定と0埋め
[width]は変換後の文字列の最小幅を指定するものです。
[`0`][width]の幅に満たない場合にゼロ埋めすることを指定するフラグです。
[[fill]align][fill]でも[width]の幅に満たない部分の文字を指定できますが、符号やプレフィックスの位置が異なります。数値として表示する場合は[fill]ではなく[`0`]が適しています。

fn main(){
    println!("「{:10}」", 123);     // 「       123」 widthに10文字を指定
    println!("「{:010}」", 123);    // 「0000000123」 widthに10文字を指定 ゼロ埋め

    // fillで0を指定した場合と`0`の違い 符号やプレフィックスの位置に注目
    println!("「{:+010}」", -123.456);  // 「-00123.456」ゼロ埋め
    println!("「{:0>+10}」", -123.456); // 「00-123.456」>の前に0があるためfillと判定される
    println!("「{:#010b}」", 5);      // 「0b00000101」 ゼロ埋め
    println!("「{:0>#10b}」", 5);     // 「000000b101」 これは2進数だが、16進数と区別ができない
}

##['.' precision] - 小数点以下の桁数を指定する
これは浮動小数点数の小数点以下の桁数を指定します。

fn main(){
    println!("「{:.3}」", 123.456789);  // 「123.457」 小数点以下4桁以降が丸められた
    println!("「{:.3}」", 100.0004);    // 「100.000」 四捨
    println!("「{:.3}」", 100.0005);    // 「100.001」 五入
}

##[type] - フォーマットの種類を指定する(16進数や指数表示など)
フォーマットの種類を指定します。何も書かなければdisplayになります。
Rustdocに[type]とそれに対応するトレイトの一覧が乗っています。
各トレイトにfn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result関数が定義されており、これを実装するとユーザー定義型のデータをフォーマットできるようになります。
Debug#[derive(Debug)] を書くだけで実装されます。

nothing ⇒ Display
? ⇒ Debug
x? ⇒ Debug with lower-case hexadecimal integers
X? ⇒ Debug with upper-case hexadecimal integers
o ⇒ Octal
x ⇒ LowerHex
X ⇒ UpperHex
p ⇒ Pointer
b ⇒ Binary
e ⇒ LowerExp
E ⇒ UpperExp
fn main() {
    println!("「{}」", "Display");  // 「Display」 Displayではデータの中身だけを表示
    println!("「{:?}」", "Debug");  // 「"Debug"」 Debugではリテラルと同じ表示になる
    println!("「{:x?}」", 123);     // 「7b」
    println!("「{:X?}」", 123);     // 「7B」
    println!("「{:o}」", 123);      // 「173」
    println!("「{:x}」", 123);      // 「7b」
    println!("「{:X}」", 123);      // 「7B」
    println!("「{:p}」", &123);     // 「0x7ff6d7312348」 ポインタ 要するにアドレス
    println!("「{:b}」", 123);      // 「1111011」
    println!("「{:e}」", 123.456);  // 「1.23456e2」
    println!("「{:E}」", 123.456);  // 「1.23456E2」
}

目次

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?