【C言語入門】printf関数で文字列を出力する

  • 2025.02.07
       
【C言語入門】printf関数で文字列を出力する

C言語で計算処理などを行うプログラムを作成する際、多くのケースではプログラムの処理の結果をコマンドラインに文字列として出力する処理が必要になります。

C言語では、そのような文字列を出力表示する方法の1つとしてprintf関数が用意されています。

そこで今回の記事では、printf関数の詳しい使い方について、基礎から応用まで順番に解説をしていきたいと思います!

printf関数とは?

printf関数は、C言語における標準関数と呼ばれるものの一つで、 引数に指定された書式付き文字列を画面に出力するための関数です。

フォーマット指定子と呼ばれる、表示形式を指定するための記述子と組み合わせることで、変数の値や計算結果を文字列に組み込んだり、出力表示する際の文字列の幅を変更したりなど、様々な書式の文字列を出力させることができます。

printfの使い方

printf関数はいくつかの引数を指定することで文字列を出力します。

第1引数に出力表示したい書式付き文字列を指定し、第2引数以降に文字列に組み込むのに必要な値を指定します。

基本構文は以下の通りです。

【基本構文】

printf(“書式付き文字列”, 値1, 値2, ・・・)

値は、書式の内容に合わせて必要数分を指定しましょう。

以下の例のように、文字列に値を組み込む必要がない場合には省略することができます。

【サンプルコード】

printf("HelloWorld!")

出力する文字列を改行する

C言語においては、コードで指定がされない限り文字列が改行されることはありません。

例えば、以下の例のようにprintf関数を複数回使用しても、ログ上では改行されることなく1行で表示されます。

【サンプルコード】

#include <stdio.h>

int main(void) {
    printf("sample1");
    printf("sample2");
    return 0;
}

【実行結果】

sample1sample2

文字列を改行したい場合は、改行コードである「\n」を使用しましょう。

改行したい場所に記述することで、文字列を複数行に分けることができます。

以下のサンプルコードで動作を確認してみましょう。

【サンプルコード】

#include <stdio.h>

int main(void) {
    printf("sample1\nsample2\nsample3");
    return 0;
}

【実行結果】

sample1
sample2
sample3

改行コードを挟んだ箇所で改行されているのが分かると思います。複数行の文字列を出力する際は、適切な位置での改行コードの追加を忘れないようにしましょう。

引数を指定して文字列を表示する

次に、printfの引数で指定した値を出力結果の文字列に組み込む方法について見ていきましょう。

変数などの値を元に文字列を作成したい場合は、フォーマット指定子を使用して書式の内容を設定します。

フォーマット指定子は設定できる項目が多岐に渡るため、後ほど詳しく説明を行いますが、まずは以下のサンプルコードで簡単な例を見てみましょう。

【サンプルコード】

#include <stdio.h>

int main(void) {
    char sample[] = "サンプルコード";
    printf("変数 sample の中身は %s です", sample);
    return 0;
}

【実行結果】

変数 sample の中身は サンプルコード です

上記の結果を見ると、「%s」の部分が変数の値に変化しているのが分かると思います。これがフォーマット指定子です。

このように、「%」の後ろに指定したい内容を記述することで、引数の値を任意の書式で表示できるようになります。

なお、Windows環境で実行結果が文字化けする場合は、 chcp 65001 というコマンドを実行してからもう一度やり直してみてください。

変換指定子で変数を出力結果に表示する

フォーマット指定子を使用する際に必ず記述するのが、変換指定子です。先ほどのサンプルコードで言うところの、「%s」の「s」の部分に当たります。

文字列に変数などの値を組み込みたい時に使用しますが、入れる値の型によって使う変換指定子は異なります。それぞれの変換指定子と、その指定子に対応する型の一覧を以下にまとめたので、参考にしてみてください。

変換指定子 対応する型 説明
d, i int, short 10進符号付き整数に変換
u unsigned int, unsigned short 10進符号無し整数に変換
o int, short, unsigned int, unsigned short 8進符号無し整数に変換
x, X int, short, unsigned int, unsigned short 16進符号無し整数に変換
f, F float 小数形式浮動小数点数に変換
e, E float 指数形式浮動小数点数に変換
g, G float f か e のどちらか最適な方に変換
c char 1文字を表示
s char* 文字列を表示

変数を表示する

型ごとの変換指定子の違いについて、サンプルコードでも確認してみましょう。

変換指定子を使う場合は、必ず最初に「%」を付けてから記述します。

【サンプルコード】

#include <stdio.h>

int main(void) {
    char str[] = "文字列の表示は「s」";
    char chr = 'c';
    // 文字および文字列
    printf("%s\n1文字のみの場合は「%c」\n", str, chr);

    int num = 10;
    // 整数
    printf("num:%d\n", num);

    float flt1 = 1.2345678;
    float flt2 = 12.345678;
    float flt3 = 123.45678;
    // 浮動小数点数
    printf("flt1:%f\n", flt1);
    printf("flt2:%f\n", flt2);
    printf("flt3:%f\n", flt3);
    return 0;
}

【実行結果】

文字列の表示は「s」
1文字のみの場合は「c」
num:10
flt1:1.234568
flt2:12.345678
flt3:123.456779

浮動小数点数に関しては、小数点第6位までが表示されます。小数点以下の桁数が6桁に満たない場合は余白が0で埋められ、6桁を超える場合は小数点第7位で四捨五入されます。

ですが、今回の出力結果では小数部分の桁数が5桁であるはずの flt3 の出力結果が、 123.456780 ではなく 123.456779 となってしまいました。

これはC言語で扱う浮動小数点数の精度が原因で発生する現象です。変数を宣言した際の値が 123.45678 だとしても、2進数への変換が行われた際に内部的には小数部分の値が微妙にずれることがあるためです。

この浮動小数点数の「精度」を指定する方法は、後ほど説明していきます。

パーセント記号を表示する

printf関数で、文字列としてパーセント記号(%)を使用したい場合は、「%%」と連続で記述することで表示できます。

サンプルコードで確認してみましょう。

【サンプルコード】

#include <stdio.h>

int main(void) {

    int num = 70;
    printf("現在のバッテリー残量は%d%%です", num);
    return 0;
}

【実行結果】

現在のバッテリー残量は70%です

出力結果の書式を設定する

フォーマット指定子では、変換指定子の他にも書式を指定できる項目があります。

以下が、フォーマット指定子の詳細な構文です。

【基本構文】

%[フラグ][フィールド幅][.精度][長さ修飾子]変換指定子

【フラグ】…左詰め、符号付き、桁のゼロ埋めなどを指定できます。

種類 説明
左揃えにする
0 空白の代わりに0で埋める
+ 負の場合にー、正の場合には+の符号をつけて数値を変換
(space) 負の場合にのみーの符号を付け、正の場合は半角スペースを配置して数値を変換

【フィールド幅】…文字列を何文字で出力するかを指定できます。

「最小幅」、もしくは「最小フィールド幅」とも呼びます。

変換後の文字数よりもフィールド幅が大きい場合は、フラグの設定に合わせて空白や0を埋めた状態で文字列が表示されます。(デフォルトは空白です)

文字数がフィールド幅を超過する場合は、そのまま文字列が表示されます。

【精度】…変換指定子ごとに内容が異なります。

整数の場合はフィールド幅と同じく最小幅の設定が行われますが、空白ではなく0埋めがデフォルトとなります。

浮動小数点数の場合は、小数点以下の表示する桁数を設定します。

文字列の場合は最大文字数となり、指定値以上の文字は切り捨てられるので注意が必要です。

【長さ修飾子】…実引数のデータ型のサイズを指定します。

数値の変換を行う際に使用するものです。例えば、整数の中でもint型やlong型など、サイズの異なる型がいくつか存在するため、より正確に型を指定するためのものとなります。

変換時には、指定したサイズのデータ型が渡されたものと見なして変換が行われるため、異なるサイズの値を渡すと意図しない数値が表示される可能性があります。

フィールド幅を指定して表示する

フィールド幅を変更した場合の実際の動きについて、サンプルコードで見てみましょう。

【サンプルコード】

#include <stdio.h>

int main(void) {
    int num = 12345;
    // 右詰め(デフォルト)
    printf("[%10d]\n", num);
    // 左詰め
    printf("[%-10d]\n", num);
    // 文字数がフィールド幅を超過した場合
    printf("[%1d]\n", num);
    return 0;
}

【実行結果】

[     12345]
[12345     ]
[12345]

「ー」フラグを指定することで、左詰め表示にすることもできます。

精度を指定して表示する

精度を指定した場合の動きについて、型ごとの違いをサンプルコードで確認してみましょう。

【サンプルコード】

#include <stdio.h>

int main(void) {

    int num = 12345;
    double dbl = 12.345;
    char str[8] = "sample";

    // 整数の桁数指定
    printf("num:[%.1d]\n", num);
    printf("num:[%.10d]\n", num);
    // 浮動小数点数の桁数指定
    printf("dbl:[%.1f]\n", dbl);
    printf("dbl:[%.10f]\n", dbl);
    // 文字列の文字数指定
    printf("str:[%.1s]\n", str);
    printf("str:[%.10s]\n", str);
    return 0;
}

【実行結果】

num:[12345]
num:[0000012345]
dbl:[12.3]
dbl:[12.3450000000]
str:[s]
str:[sample]

精度を指定することで、「変数を表示する」の項目で実行結果が想定と食い違っていた箇所を修正することができます。

サンプルコードの最後のprintf関数の行を、以下の内容に修正してみましょう。

【修正内容】

printf("flt3:%.6f\n", flt3);

【修正後のサンプルコード】

#include <stdio.h>

int main(void) {
    char str[] = "文字列の表示は「s」";
    char chr = 'c';
    // 文字および文字列
    printf("%s\n1文字のみの場合は「%c」\n", str, chr);

    int num = 10;
    // 整数
    printf("num:%d\n", num);

    float flt1 = 1.2345678;
    float flt2 = 12.345678;
    float flt3 = 123.45678;
    // 浮動小数点数
    printf("flt1:%f\n", flt1);
    printf("flt2:%f\n", flt2);
    // 小数点の精度を指定
    printf("flt3:%.6f\n", flt3);
    return 0;
}

【実行結果】

文字列の表示は「s」
1文字のみの場合は「c」
num:10
flt1:1.234568
flt2:12.345678
flt3:123.456780

もし上記のコードでも実行結果が変わらなかった場合は、 float 型の「丸め込み誤差」というものが原因の可能性があります。

その場合は、 float 型ではなく double 型(倍精度浮動小数点数型)を使用することで解決するケースもあります。

余った文字数を0で埋める

空白を0で埋める場合は、フラグに「0」を指定します。

【サンプルコード】

#include <stdio.h>

int main(void) {

    int num = 12345;

    printf("[%010d]\n", num);

    return 0;
}

【実行結果】

[0000012345]

指定した桁数が表示されるように0で埋めることをゼロパディング(zero-padding)と言います。出力される文字列の見た目を揃える際などによく使用されますので、覚えておきましょう。

出力結果の見た目を変更する

printf関数では、エスケープシーケンス(Mac/Linuxでは”\”, Windowsでは”¥”)を使って文字の修飾や色の変更を行うこともできます。

指定可能なコードはそれぞれ以下の通りです。

【文字装飾】

コード 説明
\x1b[1m
太文字
\x1b[4m
下線付き
\x1b[5m
点滅
\x1b[7m
文字色を背景色を反転
\x1b[0m
デフォルトに戻す

【文字色】

コード 説明
\x1b[30m
\x1b[31m
\x1b[32m
\x1b[33m
\x1b[34m
\x1b[35m
マゼンタ
\x1b[36m
シアン
\x1b[37m
\x1b[39m
デフォルトに戻す

【背景色】

コード 説明
\x1b[40m
\x1b[41m
\x1b[42m
\x1b[43m
\x1b[44m
\x1b[45m
マゼンタ
\x1b[46m
シアン
\x1b[47m
\x1b[49m
デフォルトに戻す

ただし、使用環境によっては上手く反映されないケースもあります。

また、一度設定すると元に戻すまで表示形式が変更されたままとなるので、使用の際には注意が必要です。

太文字、下線付きで文字列を表示する

エスケープシーケンスを使って文字を修飾する場合は、以下のように記述します。

【サンプルコード】

#include <stdio.h>

int main(void) {
    printf("\x1b[1mサンプル\n"); // 太文字出力
    printf("\x1b[4mサンプル\n"); // 下線付き出力
    return 0;
}

【実行結果】

サンプル
サンプル

下線付きの太文字で文字列が出力されました。

なお、環境によっては上の文字列が出力されたあとコマンドライン全体の表示がずっと下線付き・太文字になる場合があります。

その場合は、上記のサンプルコードの return 0; の前に以下の行を追加しましょう。

【追加するコード】

printf("\x1b[0m");

これによってコマンドラインの表示をデフォルトの設定に戻すことができます。

色を指定して出力結果を表示する

文字色や背景色の変更を行う場合も、同様の方法で記述します。

【サンプルコード】

#include <stdio.h>
 
int main(void) {

    printf("\x1b[31mサンプル\n"); // 文字色を変更
    printf("\x1b[47mサンプル\n"); // 背景色を変更
    
    return 0;
}

【実行結果】

サンプル

サンプル

こちらも、環境によってはコードを実行したあと文字色と背景色が変更されたままになるため、以下のリセットする場合は以下のコードを return 0; の前に入れておきましょう。

【表示をリセットするコード】

printf("\x1b[39m"); // 文字色をデフォルトに戻す
printf("\x1b[49m"); // 背景色をデフォルトに戻す

sprintf関数の使い方について

C言語にはprintfのほかに、「sprintf」という関数が存在します。

この関数を使用すると、指定の書式に沿ってフォーマットされた文字列を別の変数に格納することができます。

sprintf関数の基本構文は、以下のように記述します。

【基本構文】

sprintf(代入先の変数名, “書式付き文字列”, 値1, 値2, ・・・・)

書式の指定方法は、printf関数と同様にフォーマット指定子を使用して行います。

サンプルコードで実際の動きを確認してみましょう。

【サンプルコード】

#include <stdio.h>

int main(void) {
    char str1[] = "昨年の東京都の人口:";
    int num = 1418;

    char str2[100];

    sprintf(str2, "%s%d万人\n", str1, num);
    printf("%s", str2);
    return 0;
}

【実行結果】

昨年の東京都の人口:1418万人

まとめ

今回は、printf関数の使い方について解説してきました。

文字列を表示する処理は多くのプログラミング言語で一番最初に説明される内容です。その一方で、1行の文字列を表示するためにどのようなコードを書く必要があるかという部分には、その言語の特色が色濃く表れます。

記事の中でも紹介した通りに、C言語のprintf関数での書式の指定方法は多岐に渡るため、複雑に感じる部分も少々あったかもしれません。

ですが、printf関数はC言語を扱う上では必須の関数とも言えますので、ぜひこの記事を参考にしながら頑張ってマスターしてみてください!

関連記事

C言語の勉強方法は?

書籍やインターネットで学習する方法があります。昨今では、YouTubeなどの動画サイトやエンジニアのコミュニティサイトなども充実していて多くの情報が手に入ります。
そして、より効率的に知識・スキルを習得するには、知識をつけながら実際に手を動かしてみるなど、インプットとアウトプットを繰り返していくことが重要です。特に独学の場合は、有識者に質問ができたりフィードバックをもらえるような環境があると、理解度が深まるでしょう。

ただ、C言語に限らず、ITスキルを身につける際、どうしても課題にぶつかってしまうことはありますよね。特に独学だと、わからない部分をプロに質問できる機会を確保しにくく、モチベーションが続きにくいという側面があります。独学でモチベーションを維持する自信がない人にはプログラミングスクールという手もあります。費用は掛かりますが、その分スキルを身につけやすいです。しっかりと知識・スキルを習得して実践に活かしたいという人はプログラミングスクールがおすすめです。

プログラミングスクールならテックマニアがおすすめ!

ITスキル需要の高まりとともにプログラミングスクールも増えました。しかし、どのスクールに通うべきか迷ってしまう人もいるでしょう。そんな方にはテックマニアをおすすめします!これまで多くのITエンジニアを育成・輩出してきたテックマニアでもプログラミングスクールを開講しています。

<テックマニアの特徴>
・たしかな育成実績と親身な教育 ~セカンドキャリアを全力支援~
・講師が現役エンジニア ~“本当”の開発ノウハウを直に学べる~
・専属講師が学習を徹底サポート ~「わからない」を徹底解決~
・実務ベースでスキルを習得 ~実践的な凝縮カリキュラム~

このような特徴を持つテックマニアはITエンジニアのスタートラインとして最適です。
話を聞きたい・詳しく知りたいという方はこちらからお気軽にお問い合わせください。

     

Programmingカテゴリの最新記事