このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

例外もどき:マズイことが起きたことを伝える方法

  1. 正常な戻り値とはなり得ない値をエラー値とする。fopen()のNULL、getchar()のEOFとか。
  2. 正常な戻り値のなかで何か選んで「エラーかもしれない値」とする。それとは別に大域変数を使う。errno方式。
  3. 引数に、結果を返すべき変数(バッファ)へのポインターを渡す。関数戻り値は、成功/失敗。出力バッファ方式。
  4. 引数に、エラー番号などを入れる変数へのポインタを渡す。
  5. 構造体を返す。構造体戻し方式。

errno方式はよく使われるが、使い勝手が悪いしスレッドセーフじゃないので割愛。引数にerrno相当の変数へのポインタを渡せば少しマシだが、折衷案で中途半端だからこれも割愛。

出力バッファ方式:


#include

#define OK 0
#define NG (-1)

string_to_integer_1(char *s, int *presult)
{
int val;
int c;
for (val = 0; c = *s; s++) {
if (!isdigit(c)) return NG;
val = val*10 + (c - '0');
}
*presult = val;
return OK;
}

構造体戻し方式:


struct result {
int status; // OK or NG
int value;
};

struct result string_to_integer_2(char *s)
{
struct result r;
int val;
int c;
for (val = 0; c = *s; s++) {
if (!isdigit(c)) {
r.status = NG;
return r;
}
val = val*10 + (c - '0');
}
r.status = OK;
r.value = val;
return r;
}

エラー値が一番単純、それが使えないなら出力バッファが無難な気がする。