sprintf関数を使う
| 設計内容分類 | 組み込みソフトウェアにおけるC言語記述 |
|---|
実現したい仕様・課題
変数に格納された値を使ってログ文字列や表示文字列、通信コマンドを生成する場面は組み込みでも頻出します。数値から文字列への変換や文字列の連結を自前のコードで組み立てると、記述が煩雑になり桁処理などのバグも入りやすくなります。書式化された文字列を簡潔に生成したいというのが課題です。
設計のポイント
変数に格納された値を使用して文字列を生成する際はsprintf関数が便利です。sprintf関数は、書式文字列の中に変数の値を埋め込んで、指定したバッファへ格納します。出力フォーマットの指定により、10進(%d)、16進(%02X のような桁数・ゼロ埋め指定付き16進)、文字列(%s)など、数値を指定した形式の文字列へ変換できます。ログ出力、LCD等への表示文字列、ATコマンドのような通信コマンドの組み立てまで、幅広く活用できます。組み込みで安全に使うための注意点として、まずバッファあふれ対策があります。sprintfは書き込みサイズの上限を指定できないため、可変の文字列(%s)を扱う場合はサイズ上限を指定できるsnprintf(buf, sizeof(buf), …) の使用を推奨します。また、浮動小数点の書式(%f)を使うとライブラリのコードサイズが大きく増える処理系があるため、リソースの小さいマイコンでは整数化して出力する(例:小数1桁なら10倍した整数を%d.%dで出す)方法も検討します。処理時間も比較的大きい関数のため、割り込みハンドラ内での使用は避け、メインループ側で整形する設計とします。書式指定と引数の型の不一致は不正動作の原因になるため、コンパイラの書式チェック警告を有効にしておくことも有効です。
【コード例】
#include <stdio.h>
int value = 123;
char str[] = "test";
char buf[256];
sprintf(buf, "dec=%d, hex=0x%02X, text=%s", value, value, str);
printf("%s", buf);
// 出力結果: dec=123, hex=0x7B, text=test
// 可変文字列を含む場合はサイズ上限付きのsnprintfを推奨
snprintf(buf, sizeof(buf), "name=%s", name);
補足情報
設計のポイント 一覧
組み込みソフトウェアにおけるC言語記述のポイント
- リングバッファで受信データを取りこぼさない
- switch-caseによるステートマシンの実装
- 割り込みハンドラは短く書く
- constを活用する(ROM配置と書き換え防止)
- ビット演算によるレジスタ・フラグ操作
- 固定幅整数型(stdint.h)を使う
- volatile修飾子を正しく使う
- 構造体の宣言にpackedを指定する
- ソースコードのエンディアン変換
- sizeofを使用する
- 特殊文字の記述にエスケープ文字を使用する
- 変数の初期化漏れを防ぐ
- 外部バスの使用
- sprintf関数を使う
- 列挙型(enum)を使う
- 構造体を使う
- 標準関数を使う
- 条件演算子を使う
- インクリメント演算子を使う
- C言語記述の際はアプリ層とドライバ層に分ける



