1.18 C ライブラリでの __backspace() の再実装

関数 __backspace() は、scanf 関数ファミリにより使用され、fgetc() レベルで stdio 構成のターゲットを変更する場合は再実装する必要があります。

scanf に似た独自の関数を実装しない限り、通常は __backspace() を直接呼び出す必要はありません。
構文は以下のとおりです。
int __backspace(FILE *stream);
__backspace(stream) は、ストリームから文字を読み出した後でのみ呼び出す必要があります。例えば、書き込みやシークの後、またはファイルを開いた直後に呼び出すことはできません。この関数は、ストリームから読み出された最後の文字をストリームに返し、次の読み出し操作によって同じ文字をストリームから再度読み出せるようにします。つまり、scanf によってストリームから読み出されたが不要になった文字(scanf の動作が終了する理由となった文字)が、その次の関数でストリームから正しく再度、読み出されるようにします。
__backspaceungetc() とは異なります。これは、scanf ファミリの関数の終了後に単一の文字を確実に返すための関数です。
__backspace() によって返される値は 0(成功)または EOF(失敗)です。EOFは、ストリームから文字が読み出されなかった場合など、誤った方法で使用された場合にのみ返されます。正しく使用されている限り、__backspace() は必ず 0 を返す必要があります。これは scanf ファミリの関数がエラー復帰をチェックしないためです。
__backspace()ungetc() との関係は以下のとおりです。
  • ストリームに __backspace() を適用し、同じストリーム内の文字に ungetc() を適用した場合、それ以降の fgetc() 呼び出しでは ungetc() によって返された文字を最初に返し、次に __backspace() によって返された文字を返す必要があります。
  • ungetc() でストリームに文字を返し、その文字を fgetc() で読み出してから後退する場合、fgetc() によって読み出される次の文字は、ストリームに返された文字と同じ文字である必要があります。つまり、__backspace() 処理は fgetc() 処理を取り消す効果を持っている必要があります。ただし、__backspace() の呼び出し後に再度 ungetc() を呼び出した場合にそれが成功する必要はありません。
  • ストリームに対して文字が ungetc() された直後に、読み出しが実行されることなく、さらにもう 1 文字が __backspace() されるような状況はありません。これは、__backspace() の呼び出しが、必ず fgetc() の呼び出し後に実行される必要があるため、その呼び出しのシーケンスが不正となるためです。__backspace() の実装を書き込んでいる場合、ストリームに対して 1 文字が ungetc() された直後に、読み出しが実行されることなく、__backspace() されるような状況はありません。
関連する概念
1.14 C ライブラリ printf ファミリ関数
1.15 C ライブラリ scanf ファミリ関数
1.16 C ライブラリで高レベルライブラリ関数の直接使用を有効化するための低レベルライブラリ関数の再定義
1.17 C ライブラリ関数 fread()、fgets()、および gets()
1.19 C ライブラリでの __backspacewc() の再実装
1.20 C ライブラリでのターゲットに依存するシステム入出力関数の再定義
関連する参考文書
1.12 C および C++ ライブラリでの入出力関数のカスタマイズ
1.13 C および C++ ライブラリ内での低レベル関数のターゲット依存関係
非機密扱いPDF file icon PDF 版ARM DUI0808CJ
Copyright © 2014, 2015 ARM.All rights reserved.