AVR Libc Home Page AVRs AVR Libc Development Pages
Main Page FAQ Library Reference Additional Documentation Example Projects

<stdio.h>: 標準入出力(Standard IO fascilities)


Detailed Description

 #include <stdio.h> 

標準入出力への案内

このファイルはavr-libcで実装されている標準入出力を定義します。ハードウェアの性質上、制限された標準入出力サブセットが実装されています。
ファイル機能はなく、デバイスIO入出力だけが装備されています。Operating Systemがないので、標準入出力を利用するには、アプリケーションは使用するデバイスについて詳細なデバイス入出力方法を提供しなければなりません。

メモリ空間の制限により、いくつかの機能は全く実装されていません(例えばprintfのいくつかの変換など)。それでも使いたい人には注意しておきます: printfscanf の類の関数は、有名な "Hello, world!"プログラムのようにごくありふれたものではありますが、実際にはかなり複雑なもので、この関数のはかなり大量のプログラムコードスペースを食いつぶします。また、これらの関数はランタイムによりフォーマット文字列を通訳するという動作の性質上、決して速いものではありません。可能な限り、avr-libcが提供する決めうちの変換を行うような関数を利用する方がコードサイズ、速度共に有利です。

コード・サイズをとるか、機能をとるか〜チューニング可能オプション

プログラマにサイズを取るか機能を取るかの選択を許すため、printfの中核部分を持つ関数 vfprintf() は、リンカオプションにより異なった味付けが選択できます。詳細は vfprintf()の解説をお読みください。同様なことが vfscanf() やscanf ファミリーの関数にも適用されます。

選択されたAPIのアウトライン

標準ストリーム stdin, stdout, stderr が提供されていますが、標準的なCと異なります。avr-libcには接続できるデバイスがないので、ストリームはアプリケーションが動き出した後も予め初期化はされていません。また、avr-libcにはファイルなんてないので、何らかのデバイスにストリームを結合するfopen()関数もありません。 (note 1参照)。代わりに、ストリームをデバイスに関連づける関数 fdevopen() が用意されています。デバイスは1文字を送る関数・1文字を受信する関数・もしくは両者を提供する必要があります。avr-libcではテキストとバイナリのストリームに特に違いはありません。文字\\nは文字としてデバイスのput()関数に送られます。もしデバイスが復帰改行 CR \r 文字を、行送り LF の前に送りたければ、put()ルーチンはその動作を組み込まなければなりません。( note 2参照。)

ユーザー提供FILE構造の設定について、 fdevopen() に代わるもう1つの方法として、 fdev_setup_stream() が利用できます。

改行文字(newline) の復帰改行(carriage return) への自動変換にご注意ください。改行文字(newline)へのこの手続きはバイナリ転送を破壊します。バイナリ転送が要求されれば、自動変換は行われません。そのかわり、CR-LFシーケンスを意図した文字列は、明示的に"\r\n"を用いなければなりません。

簡単に言えば、読み込みのためのストリームを開く最初の fdevopen()、出来上がったストリームがstdinの別名を持つことになります。同様に、書き込みのためのストリームを開く最初の fdevopen()は、stdoutstderrの別名を持ちます。こうして、入出力両者についてopenが成立すれば、3つの標準入出力が同等なものとなります。これら3つのストリームは区別不可能で、fclose() はこれらのストリームを全てクローズします。 (note 3)

追加のユーザーデータを、fdev_set_udata() を用いてストリームに結びつけることが可能です。バックエンドのget/put関数ではfdev_get_udata() を介してユーザーデータを拾い上げ、それに応じた処理を行わせることができます。たとえば、単独の put 関数で2つの異なるUART機構を利用することができます。(※使用するUARTの切り替えを行わせる)と会話することができます。また、put/get関数が内部状態をお互いに共有することもできます。??

FLASH-ROM内に置けるフォーマット文字列

printfscanf ファミリーの関数は2つのシリーズを持っています。1つは標準の名前の関数で、フォーマット文字列はSRAM上にあると見なしています。もう1つは末尾に "_P" がついた名前の関数で、フォーマット文字列はFLASH ROM内にあると見なしています。マクロ PSTR( Program Space String Utilitiesで解説しています ) により、これらのプログラムメモリ上フォーマット文字列を簡単に宣言することができます。

標準入出力を、malloc()を使わずに使用する

デフォルトでは、fdevopen() は、浮動小数点版の printf/scanfと同様、malloc() を要求します。μコントローラの限定された環境ではこれは多くは望まれないことですので、malloc() なしで動作する別の手段が提供されています。

マクロ fdev_setup_stream() が提供されています。これはユーザー提供 FILE bufferを標準入出力操作に利用します。浮動小数点操作が必要な場合は、ユーザー提供バッファは浮動小数点データやscanf処理データの内部バッファとして使われます。

Example

    #include <stdio.h>

    static int uart_putchar(char c, FILE *stream);   // 関数宣言

    static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
                                             _FDEV_SETUP_WRITE);   

    static int
    uart_putchar(char c, FILE *stream)
    {

      if (c == '\n')
        uart_putchar('\r');  //※単に c='\r'; の方が良いような気もする
      loop_until_bit_is_set(UCSRA, UDRE);
      UDR = c;
      return 0;
    }

    int
    main(void)
    {
      init_uart(); //※他で定義されている必要がある
      stdout = &mystdout;  //※stdoutをオーバーライドできる→printfで望む出力が可能になる
      printf("Hello, world!\n");

      return 0;
    }

この例題では初期化に fdev_setup_stream() ではなく、FDEV_SETUP_STREAM() を使っています。これを使うと全てのデータ初期化がCのスタートアップでなされます。

もしこのように初期化されたストリームが不要になった時には、マクロ fdev_close() にて破棄することができます。オブジェクト自身もこれにより破棄されます。fclose() をコールする必要はありません。fclose()のコール自体は無害ですが、これは free() への未定義参照エラーを引き起こし、リンカーに malloc モジュールを埋め込むよう要請してしまいます。

Notes

Note 1:
fopen()互換のデバイス抽象化を組み込むことは可能ではあるでしょうが、これは文字列を解釈し、アプリケーションが提供するテーブルを参照して情報を取り出す操作が要求されます。このアプローチは採用されませんでした。
Note 2:
これは基本的にはUnixのアプローチを踏襲しています。端末などのデバイスが特別な処理を要するなら、この機能を実現するのはターミナルのデバイスドライバで行われます。UARTインタフェースと通信する fdevopen() のための 適切な簡単な関数 put()は以下のようになります。
    int
    uart_putchar(char c, FILE *stream)
    {

      if (c == '\n')
        uart_putchar('\r');
      loop_until_bit_is_set(UCSRA, UDRE);
      UDR = c;
      return 0;
    }

Note 3:
この仕様は、おのおののストリームのフルコピーを持つよりは別名管理の方がコストが少ないことから選択されました。完全な標準ストリームを構築することは便利なことだとは思いますが。fprintf(mystream, ...) の代わりにprintf() を用いる利点は、タイピングの労力を削減するだけではありません。固定数パラメータをレジスタ経由で渡すのに比べれば、可変数パラメータをスタック経由で渡すのは引数の並べ替えを要します。また、stdin 決め打ちにしてパラメータを1つ省略することはいくらかの実行時間節約になります。

Defines

#define FILE   struct __file
#define stdin   (__iob[0])
#define stdout   (__iob[1])
#define stderr   (__iob[2])
#define EOF   (-1)
#define fdev_set_udata(stream, u)   do { (stream)->udata = u; } while(0)
#define fdev_get_udata(stream)   ((stream)->udata)
#define fdev_setup_stream(stream, put, get, rwflag)
#define _FDEV_SETUP_READ   __SRD
#define _FDEV_SETUP_WRITE   __SWR
#define _FDEV_SETUP_RW   (__SRD|__SWR)
#define _FDEV_ERR   (-1)
#define _FDEV_EOF   (-2)
#define FDEV_SETUP_STREAM(put, get, rwflag)
#define fdev_close()
#define putc(__c, __stream)   fputc(__c, __stream)
#define putchar(__c)   fputc(__c, stdout)
#define getc(__stream)   fgetc(__stream)
#define getchar()   fgetc(stdin)

Functions

int fclose (FILE *__stream)
int vfprintf (FILE *__stream, const char *__fmt, va_list __ap)
int vfprintf_P (FILE *__stream, const char *__fmt, va_list __ap)
int fputc (int __c, FILE *__stream)
int printf (const char *__fmt,...)
int printf_P (const char *__fmt,...)
int vprintf (const char *__fmt, va_list __ap)
int sprintf (char *__s, const char *__fmt,...)
int sprintf_P (char *__s, const char *__fmt,...)
int snprintf (char *__s, size_t __n, const char *__fmt,...)
int snprintf_P (char *__s, size_t __n, const char *__fmt,...)
int vsprintf (char *__s, const char *__fmt, va_list ap)
int vsprintf_P (char *__s, const char *__fmt, va_list ap)
int vsnprintf (char *__s, size_t __n, const char *__fmt, va_list ap)
int vsnprintf_P (char *__s, size_t __n, const char *__fmt, va_list ap)
int fprintf (FILE *__stream, const char *__fmt,...)
int fprintf_P (FILE *__stream, const char *__fmt,...)
int fputs (const char *__str, FILE *__stream)
int fputs_P (const char *__str, FILE *__stream)
int puts (const char *__str)
int puts_P (const char *__str)
size_t fwrite (const void *__ptr, size_t __size, size_t __nmemb, FILE *__stream)
int fgetc (FILE *__stream)
int ungetc (int __c, FILE *__stream)
char * fgets (char *__str, int __size, FILE *__stream)
char * gets (char *__str)
size_t fread (void *__ptr, size_t __size, size_t __nmemb, FILE *__stream)
void clearerr (FILE *__stream)
int feof (FILE *__stream)
int ferror (FILE *__stream)
int vfscanf (FILE *__stream, const char *__fmt, va_list __ap)
int vfscanf_P (FILE *__stream, const char *__fmt, va_list __ap)
int fscanf (FILE *__stream, const char *__fmt,...)
int fscanf_P (FILE *__stream, const char *__fmt,...)
int scanf (const char *__fmt,...)
int scanf_P (const char *__fmt,...)
int vscanf (const char *__fmt, va_list __ap)
int sscanf (const char *__buf, const char *__fmt,...)
int sscanf_P (const char *__buf, const char *__fmt,...)
int fflush (FILE *stream)
FILE * fdevopen (int(*put)(char, FILE *), int(*get)(FILE *))

Define Documentation

#define _FDEV_EOF   (-2)
 

デバイス読み込み中に end-of-file 状態を検出したことを示す

fdevopen() で指定する get 関数内で使われる

#define _FDEV_ERR   (-1)
 

デバイス読み込み中に 何らかのエラーを検出したことを示す

fdevopen() で指定する get 関数内で使われる

#define _FDEV_SETUP_READ   __SRD
 

fdev_setup_stream() で読み込みストリーム生成を指定する

#define _FDEV_SETUP_RW   (__SRD|__SWR)
 

fdev_setup_stream() で読み書きストリーム生成を指定する

#define _FDEV_SETUP_WRITE   __SWR
 

fdev_setup_stream() で書き込みストリーム生成を指定する

#define EOF   (-1)
 

EOF は、多くの標準入出力関数でエラーを表すため定義されています。AVRプラットホーム(現時点で)は実際のファイルの抽象化を含んでいないので、元々の意味 "End Of File"はいくらか意味不明と言うことになります。

 
#define fdev_close
 ) 
 

このマクロはストリーム関連のライブラリリソース(メモリなど)を解放します。ストリームが不要になったとき、ストリームオブジェクト自身を解放する前にこのマクロが呼ばれるべきです。

(現在のところ、このマクロは何もしません。しかし将来のライブラリバージョンでは変更されるかもしれません。

#define fdev_get_udata stream   )     ((stream)->udata)
 

このマクロは、FILE ストリームオブジェクト内のユーザー定義データポインタを取得します。

#define fdev_set_udata stream,
 )     do { (stream)->udata = u; } while(0)
 

このマクロはユーザー定義のデータへのポインタを、 FILE ストリームオブジェクトへ挿入します。

このユーザーデータは fdevopen() 関数で提供される get/put関数の状態を追っかけるのに便利です。
※get/putの状態を得たり、これらに対し動作を指示したりするのにこのデータを用いるという意味?

#define FDEV_SETUP_STREAM put,
get,
rwflag   ) 
 

ユーザー提供標準入出力ストリームの初期化を行います

このマクロは fdev_setup_stream() と似ていますが、こちらは FILE型の変数に対する初期化に用いられます。

引数については fdev_setup_stream() の解説をご覧ください。

#define fdev_setup_stream stream,
put,
get,
rwflag   ) 
 

ユーザー提供標準入出力ストリームの初期化を行います

このマクロはユーザー提供バッファストリームを取得し、それを標準入出力操作に使えるストリームへと構築します。メモリ動的取得で使える fdevopen() と似ています。セットアップされるバッファは FILE型が要求されます。
This macro takes a user-supplied buffer stream, and sets it up as a stream that is valid for stdio operations, similar to one that has been obtained dynamically from fdevopen(). The buffer to setup must be of type FILE.

引数 put / get は、 fdevopen() のそれと同様です。

引数 rwflag は、 _FDEV_SETUP_READ, _FDEV_SETUP_WRITE, or _FDEV_SETUP_RW の内から選択します。
それぞれ、read、write、read/writeを指定します。

Note:
fdev_setup_stream() による標準入出力ストリームへの割り当ては行われません。標準ストリームで使いたい場合、ユーザー自身で割り当てる必要があります。※stdout=&mystream のように。標準入出力を、malloc()を使わずに使用するの下方にあるサンプルコードを参照ください。
#define FILE   struct __file
 

FILE は隠された構造体で、いろいろな標準入出力関数で受け渡しされます。

#define getc __stream   )     fgetc(__stream)
 

マクロ getcfgetc()と同等機能を、より高速なマクロで実現します。
メモリの制約により、 avr-libcにおいては、これは単なる fputcへのAliasです。

#define getchar void   )     fgetc(stdin)
 

マクロ getcharstdinから1文字を読み込みます。返す値とエラー時の挙動は fgetc()と同様です。.

#define putc __c,
__stream   )     fputc(__c, __stream)
 

マクロ putc は fputc() と同等機能を、より高速なマクロで実現します。
スペースの制約により、avr-libcではこれは単なるfputc へのエイリアスで実現しています。

#define putchar __c   )     fputc(__c, stdout)
 

マクロ putchar は1文字をstdoutに送ります

#define stderr   (__iob[2])
 

エラー出力用のストリーム。特別に設定しない限り、stdoutと同等です。

stderr を他のストリームに向けたい場合、現在ある stderr をクローズせずに(クローズすればstdoutもクローズされます)、実行するfdevopen() の返す値を明示的にstderrにわりつけなければなりません。

#define stdin   (__iob[0])
 

単純な関数(ストリーム引数を持たない)により入力ストリームとして利用できるストリーム。

fdevopen()で開かれた最初の読み込み用ストリームはstdin に割り当てられます。

#define stdout   (__iob[1])
 

単純な関数(ストリーム引数を持たない)により出力ストリームとして利用できるストリーム。

fdevopen()で開かれた最初の書き込み用ストリームはstdinstderr 双方に割り当てられます。


Function Documentation

void clearerr FILE *  __stream  ) 
 

エラーやend-of-file(EOF)フラグをクリアします。

int fclose FILE *  __stream  ) 
 

この関数はストリームを閉じ、このストリームからの今後の入出力を禁止します。

fdevopen() を使って生成したストリームの使用を終わる場合は、割り当てられた内部リソースの解放のためにfclose() を読み出す必要があります。

fdev_setup_stream()FDEV_SETUP_STREAM() を使って生成したストリームについては、代わりにfdev_close() を使ってください。

この関数は現時点では常に 0 (成功)を返します。

FILE* fdevopen int(*)(char, FILE *)  put,
int(*)(FILE *)  get
 

この関数は fopen() の代わりとして用意されました。

この関数は、現実のデバイス実装がアプリケーションによって提供されているデバイスに対し、ストリームを開きます。成功すれば開かれたストリームのために作られた構造体へのポインタを返します。
ストリームを開くのが失敗に終わる原因としては、put/getどちらの引数も提供されていない全くI/O処理がないストリームを開こうとした場合、新しいストリームを開くのに充分なダイナミックメモリがない場合などが挙げられます。(※malloc()でメモリを確保します)

put 関数へのポインタが提供された場合、ストリームは書き込み用として開かれます。putとして渡された関数は2つの引数をとります。最初の引数はデバイスに書き出す文字データ、2番目の引数はFILE構造体へのポインタです。put用関数は出力が成功した場合 0 を返し、文字がデバイスへ送信できなかった場合は 0以外の値を返すことが要求されます。

get 関数へのポインタが提供された場合、ストリームは読み込み用として開かれます。getとして渡された関数は一つの引数を持ち、FILE構造体へのポインタを与えられます。get用関数はデバイスから得られた(signed) int 型で持ち帰ります。デバイスからの読み出しエラーが生じた場合は値 _FDEV_ERR を、EOFコンディションを検出した場合は _FDEV_EOF を返すことが要求されます。

put/get両方の関数が提供された場合は、ストリームは読み書き両用として開かれます。

読み込み専用として開かれた最初のストリームは stdin に割り当てられ、書き込み専用として開かれた最初のストリームは stdout stderr の2つに割り当てられます。

fdevopen()calloc() (さらには malloc()) を呼び出し、新しいストリームのための記憶領域を確保します。

Note:
マクロ  __STDIO_FDEVOPEN_COMPAT_12 が <stdio.h>の前に宣言された場合、avr-libc version 1.2 以前との互換性のために前バージョンの fdevopen() が選択されます。これはもっぱら大きな書き換えなしで過去のソース資産を利用するためのものです。新しいコードには使用しないでください。
int feof FILE *  __stream  ) 
 

ストリームのファイル終端 ( end-of-file , EOF) フラグをチェックします。
このフラグはclearerr()をコールすることによってのみクリアできます。

int ferror FILE *  __stream  ) 
 

ストリームのエラーフラグをチェックします。このフラグはclearerr()をコールすることによってのみクリアできます。

int fflush FILE *  stream  ) 
 

ストリームをフラッシュする

これはソースコードの互換性のためだけに存在するもので、なんの動作もしません。標準入出力の実装はバッファリングは行っていません。

int fgetc FILE *  __stream  ) 
 

関数 fgetc はストリームから1文字読み出します。文字値またはEOF値(end-of-file状況、又は何らかのエラー発生時)を返します。
EOFとエラーを区別するためfeof() またはferror() を使用する必要があります。

char* fgets char *  __str,
int  __size,
FILE *  __stream
 

最大 (size-1)バイトをストリームから読み出します。NewLine(改行)文字に出会った場合は文字列を str で示されたバッファに保存します。読み出し中エラーに出会わない限り、文字列はNUL文字で終わります。

エラーがなければ文字列へのポインタ(str)が返されます。何らかのエラーが起こった場合は関数はNULLを返し、ストリームのエラーフラグを返します。

int fprintf FILE *  __stream,
const char *  __fmt,
  ...
 

関数fprintf はストリームへ書式付き出力をおコアいます。詳細は vfprintf() をご覧ください。

int fprintf_P FILE *  __stream,
const char *  __fmt,
  ...
 

書式文字列 fmt をプログラムメモリに持つことができる fprintf() のバリエーション。

int fputc int  __c,
FILE *  __stream
 

関数 fputc は文字 c (intとして渡されます) をストリームに送ります。
通常は文字の値を返しますが、エラー時はEOFを返します。

int fputs const char *  __str,
FILE *  __stream
 

引数 str が指す文字列を ストリーム stream に書き込みます。

成功時は 0 を、エラー時は EOF値を返します。

int fputs_P const char *  __str,
FILE *  __stream
 

str を プログラムメモリ内に置くことができるfputs()のバリエーション。

size_t fread void *  __ptr,
size_t  __size,
size_t  __nmemb,
FILE *  __stream
 

ストリーム stream から、size バイトの大きさのオブジェクトを nmemb 個読み込み、ptrで示されたバッファに保存します。

読み込めたオブジェクト数を返します。エラーまたはend-of-file が起こらない限りは nmemb になります。EOFとエラーを区別するためfeof() and ferror() を使用する必要があります。

int fscanf FILE *  __stream,
const char *  __fmt,
  ...
 

関数fscanf は、stream から書式付き入力する機能を持ちます。

詳細はvfscanf() を参照ください。

int fscanf_P FILE *  __stream,
const char *  __fmt,
  ...
 

書式指定文字 fmt をプログラムメモリ内に置くことができる fscanf() のバリエーションです。

size_t fwrite const void *  __ptr,
size_t  __size,
size_t  __nmemb,
FILE *  __stream
 

ptrで示されたバッファから、ストリーム stream へ、size バイトの大きさのオブジェクトを nmemb 個書き込みます。

書き込めたオブジェクト数を返します。エラーが起こらない限りは nmemb になります。

char* gets char *  __str  ) 
 

fgets() と似ていますが、ストリーム名指定引数がなく stdin ストリームに対して処理を行う点、改行文字は文字列に含まれない点が異なります。関数をコールする側は、読み込まれる文字列に対し充分な保存領域を確保しておかなければなりません。

int printf const char *  __fmt,
  ...
 

関数 printf は書式付き出力をstderrストリームに対し行います。詳しくは vfprintf()を参照ください。

int printf_P const char *  __fmt,
  ...
 

書式指定文字列 fmt をプログラムメモリ内に置くことができるprintf() のバリエーションです。

int puts const char *  __str  ) 
 

str が指す文字列と末尾の newline 文字を stdout に書き込む。

int puts_P const char *  __str  ) 
 

文字列 str をプログラムメモリ内に置くことができる puts() のバリエーションです。

int scanf const char *  __fmt,
  ...
 

関数 scanf は書式付き入力を ストリーム stdin から行います。

詳細はvfscanf() を参照ください。

int scanf_P const char *  __fmt,
  ...
 

書式指定文字列 fmt をプログラムメモリ内に置くことができる scanf() のバリエーションです。

int snprintf char *  __s,
size_t  __n,
const char *  __fmt,
  ...
 

sprintf()と似ていますが、s が無制限に大きくなる可能性があったsprintfと異なり、文字列末端のNULを含め n 文字以上は変換しないよう制限を掛けます。

充分なスペースがあれば、変換の結果 s に書き込まれた文字列の文字数を返します。

int snprintf_P char *  __s,
size_t  __n,
const char *  __fmt,
  ...
 

書式指定文字列 fmt をプログラムメモリ内に置くことができる snprintf() のバリエーションです。

int sprintf char *  __s,
const char *  __fmt,
  ...
 

書式つき出力結果を文字列 s に出力できる printf() のバリエーションです。

int sprintf_P char *  __s,
const char *  __fmt,
  ...
 

書式指定文字列 fmt をプログラムメモリ内に置くことができるsprintf() のバリエーションです。

int sscanf const char *  __buf,
const char *  __fmt,
  ...
 

関数sscanfbuf で示されたバッファを読み込んで書式化された入力を 行います。

詳細はvfscanf() を参照ください。

int sscanf_P const char *  __buf,
const char *  __fmt,
  ...
 

書式指定文字列 fmt をプログラムメモリ内に置くことができるsscanf()のバリエーションです。

int ungetc int  __c,
FILE *  __stream
 

ungetc() 関数は 文字 c(unsigned charに変換されている)を stream で示される入力ストリームに押し戻します。押し戻された文字は次のそのストリームからの読み出しで読み込まれます。現在のところ、1文字だけ押し戻すことができます。

ungetc() 関数は(unsigned charに変換後の)押し戻した文字の値を返します。操作が失敗してストリームを変更できなかった場合はEOF値を返します。

int vfprintf FILE *  __stream,
const char *  __fmt,
va_list  __ap
 

vfprintf は、printfファミリの中核をなすものです。これは、fmt で渡される書式(フォーマット)文字列の制御に従って、値をストリームに出力します。出力すべき値は可変引数リスト ap で渡されます。

vfprintf はストリームに書き込まれた文字数を返します。エラー発生時には EOF値を返します。現時点では、エラーはストリームが書き込み用として開かれていない場合のみ発生します。

フォーマット文字列は0個以上の指令から成り、そのまま出力ストリームに渡される通常文字( % 以外)と、変換指定文字から成ります。これらはそれぞれ0個以上の引数を採ります。各々の変換指定は、'%'で始まります。続く引数は変換指定子と型も含め符合がとれていなければなりません。'%'の後に、以下のような文字が付きます。

※例:%-10.4f  '-'がフラグ、10.4がオプション、fが変換指定子 (10はフィールド幅指定、4は精度指定))

  • 0個以上のフラグ:
    • #  値は "別の形式" に変換されます。c, d, i, s, u変換(文字、数値、、文字列、)についてはこのオプションは特に働きを持ちません。o 変換(符号なし8進数)に関して、出力の最初の1文字は0に強制され、桁数が増えます(ただし、明示的に精度指定フォーマットされているため、既にゼロが先頭についている場合を除く)。 x 、X 変換(16進)の場合、ゼロでない結果は "0x" もしくは "0X"の形式となります。
    • 0 (zero)   すべての変換に関して、変換値の左側にはブランク(スペース)ではなく 0 があてがわれます。もし数値変換(d, i, o, u, i, x, and X)で精度(後述)が与えられたときは、 0 フラグは無視されます。
      Zero padding. For all conversions, the converted value is padded on the left with zeros rather than blanks. If a precision is given with a numeric conversion (d, i, o, u, i, x, and X), the 0 flag is ignored.
    • -   負のフィールド幅フラグ; 変換された値はフィールド境界に対し左寄せされます。変換された値は右側にブランクがあてがわれます。(左側の場合はブランク又は0) '-'と'0'が両方指定された場合は'-'の指定が優先されます。
    • ' ' (space)    符号付き数値変換 (d、i)時、正の数表示の前にブランクをつける.
    • +     符号付き数値変換 (d、i)時、正の数表示の前に必ず符号(+ or -)をつける。Spaceより優先される。
  • オプションの10進数数値文字列は、最低のフィールド幅を指定します。変換された値がフィールド幅より少ない文字数の場合は、フィールド幅を埋めるために左側(左寄せフラグが与えられた場合は右側)にスペースがあてがわれます。
    ※例:%8d=幅8文字で右寄せ(左側にスペースをつけて8文字にする)
  • オプションの「精度」(小数点以下表示桁数)は、上記のフィールド幅指定10進数値に続くピリオドに10進数数値文字列が続く形式です。数値文字列が省略された場合は精度は 0 と見なされます。これは、 d, i, o, u, x, X 変換に置いては表示される最下位桁を指定し、s変換(文字列)の場合は表示される最大の文字数の制限を指定します。
  • オプションの l (小文字のL)は長さ(データのサイズ)を調整します。d, i, o, u, x, X 変換では、変換数値を int ではなく "long int" として変換する事を指定します。
    ※例:%ld=32bit整数変換
  • 変換形式を指定する文字が続きます。変換指定子とその意味は以下のようになっています。
    • d,i,o,u,x,X   int型(もしくはintに型変換できるその他の型) の引数を符号付き10進数 (d,i)、符号なし8進数(o)、符号なし10進数(u)、符号なし16進数(x,X)表記で変換します。x変換では文字 "abcdef" が、X変換では文字 "ABCDEF" が使われます。精度指定オプションがあれば、表示されなければならない桁数の最小値を与えます。変換された結果が精度値より少ない桁数の場合は、左側にゼロが与えられます。
      ※%10.6dで123を変換→"____000123" ("_"はスペースを表す)
    • p   (void *)型の引数をuisigned intとして受け取り、#x コマンドと同様の16進変換を行います。
    • c   int型の引数を unsigned charとして変換し、文字コードに対応する文字を表示します。
    • s   文字列(charの配列)へのポインタとして、(char *) 型の引数を受けます。配列からの文字は文字列終端のNULが出るまで出力されます。精度指定があれば、その指定文字数以上は出力されません。精度指定がない、又は文字数が文字列領域サイズより大きい場合は、文字配列は終端のNUL文字を持たなければなりません。
    • %   (%の後に) % が書かれた場合は、引数の変換は行われません('%'自体を表示します)。完全な変換指定は "%%"です。
          ※ '%'を出力するには、フォーマット文字列中に"%%"を書けばいい。%%を出力するなら%%%%。
    • eE   倍精度実数の引数をフォーマット "[-]9.999e±99"形式に変換されます。小数点前に1桁、小数点以降には精度指定と同じ桁数が表示されます。精度指定がない場合は、6桁と見なされます。精度指定が0の場合は、小数点も小数点以下桁も現れません。指数部は常に2桁表示です。指数値がゼロの場合は指数は00です。eではなくEを使う場合は、指数表現を表す文字が大文字のEになります ("[-]9.999E±99")
    • fF   倍精度実数値引数を "[-]ddd.ddd" 形式の10進表記に変換します。小数点以下の桁数は精度指定値と同じになります。精度指定がない場合は6桁と見なされます。精度指定が0の場合は、小数点も小数点以下桁も現れません。小数点が現れる場合は、小数点前に少なくとも1桁の数字があります。※0.123を.123とは変換しない
    • gG   倍精度実数値引数を、g変換の場合はf又はe(G変換の場合はF又はE)形式で変換します。精度指定は表示する桁数の指定となります。精度指定がなければ6桁として、0なら、1桁として扱われます。(e変換をした場合の)指数が-4を下回ったとき、又は数値が表示桁数指定を上回ったときにはe変換が使われます。小数部の末尾の0は取り除かれますので、小数点は小数点以下(表示桁数以内)に0以外が現れたときに限り出現します。
    • S   s変換と似ているが、FLASH上の文字列へのポインタとして扱われる点が異なります。
  • フィールド幅が狭い場合でも、数値フィールドの切り捨ては行われません。変換結果がフィールド幅より大きい場合は、フィールドは変換結果に合わせて拡大されます。

ここに述べた機能をフル実装するとかなり大きな関数になってしまいます。そこで、3種の異なった味付けのvfprintf()が用意されており、選択が可能です。

  • デフォルトのvfprintf()は浮動小数点変換以外のすべての機能を実装しています。
  • 基本的な整数・文字列変換だけなら、小型化バージョンのvfprintf()が利用できます。ただし変換フラグを使って指定する追加オプションは利用できません。これらフラグは正しく文法解析されますが、単純に無視されます。このバージョンは以下の compiler optionsで要求することができます。
       -Wl,-u,vfprintf -lprintf_min
    
  • 浮動小数点を含むフル機能版が欲しければ、以下のオプションをつけてください。
       -Wl,-u,vfprintf -lprintf_flt -lm
    
制限:
  • フィールド幅指定と精度指定は最大127です。
  • 浮動小数点変換に関しては、精度指定>0で、DBL_MAX付近の数値を変換した場合、末尾の桁が失われます。
int vfprintf_P FILE *  __stream,
const char *  __fmt,
va_list  __ap
 

書式指定文字列fmtをプログラムメモリ内に置くことができるvfprintf() のバリエーション。

int vfscanf FILE *  __stream,
const char *  __fmt,
va_list  __ap
 

書式化入力。この関数はscanfファミリの関数の中核を成すものです。

stream から文字列を読み込み、fmt で指定した方法で処理します。変換結果は変数リストap で与えられた変数に渡されます。

まず変換指定を行うためにフォーマット文字列 fmt が調査されます。変換指定を構成しないものは入力にマッチすべきテキストと判断されます。フォーマット文字列中のホワイトスペースはデータ中のどのようなホワイトスペースにも一致します(スペースが1文字もない場合も含む)。他の文字は、その文字そのものと一致すべきものとされます。データとフォーマット文字列が一致しない場合や、streamがend-of-fileを返す場合は処理が中断されます。

ほとんどの変換は、実際の変換を行う前に、ホワイトスペースを読み飛ばします。※先頭のホワイトスペースは無視

変換は文字 % で導入されます。% に続く使用可能なオプションは以下の通りです。

  • 文字 * は、変換は行うが変換結果は破棄することを指定します。これにはapで渡される引数は対応されません。
  • 文字 h は、引数が(intではなく)short intへのポインタであることを示します。
  • 文字 l  は、整数変換において、引数が (intではなく)long int へのポインタであることを指定します。もしくは、浮動小数点変換に置いてdoubleへのポインタであることを示します。

これに加えて、最大フィールド幅が0でない正の10進数整数で指定できます。これは入力ストリームから変換する最大文字数を指定します。このフィールド幅指定は最大127文字に整外されます。これはデフォルト値でもあります。(c変換の場合のデフォルト値=1を除く)

以下の変換フラグがサポートされています。

  • %  は、文字 % と照合されます。これは変換を行いません。
  • d  は、符号付き十進整数と照合されます。次のポインタはint型変数へのポインタであることが必要です。
  • i  は、符号付き整数と照合されます。次のポインタはint型変数へのポインタであることが必要です。整数は0xまたは0Xで始まっている場合は16進数として、0で始まっている場合は8進数で、それ以外の場合は10進数で変換されます。基数に適合する文字セットだけを受け入れます。
  • o  は、8進数整数と照合されます。次のポインタはint型変数へのポインタであることが必要です。
  • u  は、符号なし十進整数と照合されます。次のポインタはunsigned int型変数へのポインタであることが必要です。
    ※オリジナルのsignedは多分間違いと思われるので修正
  • x  は、符号なし16進数と照合されます。次のポインタはunsigned int型変数へのポインタであることが必要です。※上に同じ、修正
  • f  は、符号付き浮動小数点数と照合されます。次のポインタはfloat 型変数へのポインタであることが必要です。
  • e, g, E, G は、fと同等です。
  • s  は、ホワイトスペースを含まない文字と一致します。次のポインタはchar型へのポインタであることが必要です。char配列は受ける文字列とNULターミネート文字を収容するのに充分な大きさを持たなければなりません。入力文字列はホワイトスペース又は最大フィールド幅指定のうちどちらか先に来た方で切られます。
  • c  は、width(フィールド幅指定,デフォルトは1)個の文字と照合されます。次のポインタはchar型へのポインタであることが必要です。char配列は受ける文字列を収容するのに充分な大きさを持たなければなりません。この場合は末尾のNUL文字は付加されません。通常行われる先頭のホワイトスペース読み飛ばしは行われなくなります。これが必要なら明示的に先頭にSpace(ホワイトスペースと一致)を付加してください。
  • [  は、指定された文字セットで構成される一致する空ではない文字列と照合される。次のポインタはchar型へのポインタであることが必要です。char配列は受ける文字列とNULターミネート文字を収容するのに充分な大きさを持たなければなりません。通常行われる先頭のホワイトスペース読み飛ばしは行われなくなります。文字列は文字セット内文字から(又は文字セット以外から)成る文字列と合致することになります。文字セット指定は、オープンブラケット [ と、クローズブラケット ] の間にある文字と定義されます。[ の直後の文字が 曲折アクセント文字 "^"である場合は、これらの文字を除外する文字セットという意味になります。クローズブラケット文字 "]"を文字セットに加えたければ、'['もしくは'^'に続く先頭に置いてください。その他の場所だと文字セットの終端と認識されます。ハイフン文字'-'も特別な意味を持ちます。これが2つの他の文字の間に置かれると、文字コード順で2つの文字の間に位置する文字すべてが文字セットに加えられます。ハイフン文字'-'自体を加えるには、文字セットの最後、クローズブラケット文字']'の直前に置いてください。
    たとえば、[^]0-9-]クローズブラケット']'、'0'〜'9'、ハイフンを除くすべての文字セットを意味します。照合文字列は文字セットに合致しない('~'指定の場合は逆)文字が出現したところ、又はフィールド幅文字数に達したところで終わります。
  • p  は、( printf() での p のように、) ポインタ値にマッチします。次のポインタはvoid型へのポインタであることが必要です。
  • n  は、文字列とマッチさせるものではありません。代わりに、ここまでの変換で入力され消費された文字列の文字数を次のポインタを通して返します。次のポインタはint型へのポインタであることが必要です。これは変換指定とは言えませんが、* フラグで抑制することもできます。

これらの関数は代入された入力要素の個数を返します。マッチングが失敗した場合はこの個数は用意された変数より少なかったり、0 であったりすることもありえます。0を返した場合は入力は利用可能であったが、変換がうまく行われなかったことを意味します。典型的にはこれは入力文字が不正である場合たとえばa/d変換に対しアルファベット文字が与えられた等です。EOF値が返された場合は変換以前に入力が失敗したことを意味します。たとえばend-of-file状況が起こったなど。エラーやend-of-fileが変換が始まった後に起こった場合は、成功裡に終わった変換の数が返されます。

1.デフォルトで、上記で述べた変換のうち浮動小数点変換と%[変換を除くすべてが利用可能です。

2.このデフォルトでサポートされない変換に関しては、ライブラリ libscanf_flt.a で提供される拡張版で利用可能です。これらの変換はどれもランタイム内でmalloc()を使って確保される利用可能バッファを要求することに注意してください。もしもバッファが得られなかった場合は、値EOFが返されます。拡張版をリンクするは、以下のようなコンパイラフラグをリンクステージで指定してください。

     -Wl,-u,vfscanf -lscanf_flt -lm

3.第三のバージョンはスペース制限が厳しい環境向けです。このバージョンはライブラリ libscanf_min.a で提供され、リンクステージで下記のようなオプションをつけることで要求できます。

     -Wl,-u,vfscanf -lscanf_min -lm

スタンダード版の制限に加えて、このバージョンではフィールド幅指定、変換値代入禁止フラグ(*)、n指定、一般フォーマット文字マッチング機能が全くありません。変換指定に使われない文字はホワイトスペース(通常は任意の文字数のホワイトスペースにマッチするもの)も含めすべて無視されます。しかしながら、フォーマット内の先頭部分のホワイトスペーススキップ機能は使えます。

int vfscanf_P FILE *  __stream,
const char *  __fmt,
va_list  __ap
 

書式指定文字列 fmt をプログラムメモリ内に置くことができるvfscanf()のバリエーションです。

int vprintf const char *  __fmt,
va_list  __ap
  vfprintf() のような可変引数リストの書式化出力をstdout に対して行う。

詳細はvfprintf() 参照。

int vscanf const char *  __fmt,
va_list  __ap
 

vfscanf() のように書式入力をstdinから行い可変引数リストの変数に納める。

詳細はvfscanf() 参照。

int vsnprintf char *  __s,
size_t  __n,
const char *  __fmt,
va_list  ap
 

vsprintf() と似ていますが、 最大 n 文字(末端のNUL文字含む)に制限して s が無制限に大きくなるのを防ぎます。

充分なスペースがあれば、変換して s に書き込まれた文字列の長さを返します。

int vsnprintf_P char *  __s,
size_t  __n,
const char *  __fmt,
va_list  ap
 

書式指定文字列 fmt をプログラムメモリ内に置くことができる vsnprintf() のバリエーションです。

int vsprintf char *  __s,
const char *  __fmt,
va_list  ap
 

sprintf() に似ていますが、可変引数を受け付けます。

int vsprintf_P char *  __s,
const char *  __fmt,
va_list  ap
 

書式指定文字列 fmt をプログラムメモリ内に置くことができる vsprintf() のバリエーションです。


Automatically generated by Doxygen 1.4.1 on 23 Jan 2006.