getChar

呼ばれるたびに1文字づつ読み込んで返す関数 getChar を作成する。

実際のファイルからの読み込みは行単位で行う。

読み込んだ文字列をreadBufferに保存しておき、
現在の読み込み位置をreadIndexに保存しておく。

読み込み位置の初期値は、-1にしておき、読み込み位置が-1ということは、
読み込んだ文字列が空っぽであることを意味する。

現在位置が-1の時に呼び出されると、次の行を読み込み、
現在位置を0に設定する。

読み込んだ文字列から1文字返し、現在位置を1つ進める。
現在位置が、読み込んだ文字列の長さと同じになったら、改行コードを返し、
現在位置を-1に設定する。

ファイルの終わりに達したら、EOFを返す。


//********************************************************
// 入力ファイル用クラス
//********************************************************
public class Reader
{
private const char EOF = '\0';
private const char NEWLINE = '\n';

private System.IO.StreamReader reader;
private bool IsOpen = false;
private string fileName = "";
private string readBuffer = "";
private int readIndex = -1;

//****************************************************
// 初期化
//****************************************************
public Reader(string fileName)
{
this.fileName = fileName;
}
//****************************************************
// 終了
//****************************************************
~Reader()
{
Close();
}
public void Close()
{
//OPENしてたら
if (IsOpen)
{
//CLOSEする
reader.Close();
reader = null;
IsOpen = false;
}
}

//****************************************************
// 入力ファイルから1文字ずつ読む
//****************************************************
public char getChar()
{
//まだOPENしてなかったら
if (!IsOpen)
{
//OPENする
reader = new System.IO.StreamReader(fileName, System.Text.Encoding.GetEncoding("Shift_JIS"));
IsOpen = true;
}

//現在位置が初期化されていたら (読み込み用バッファが空っぽ)
if (readIndex < 0)
{
//次の行を読む
readBuffer = reader.ReadLine();

//次の行がなければ
if (readBuffer == null)
{
return EOF;
}

//現在位置を行の先頭に位置づける
readIndex = 0;
}

//現在位置が読み込み用バッファの最後に達したら
if (readIndex >= readBuffer.Length)
{
//現在位置を初期化する
readIndex = -1;
//改行コードを返す
return NEWLINE;
}

//読み込み用バッファから1文字返して、現在位置を1つ進める
return readBuffer[readIndex++];
}
}