• ベストアンサー

atoiでの文字列以外のエラー処理(初心者)

超初心者の質問です 1~3の数値のみ入力してほしい場合 _getts(Word); number = atoi(Word); if( 1<= nunber && 11 >= nunber ){ brerk }; とするとnunberの中に1~11が入るはずですが これを実行すると文字列を入力したときにヘンテコなエラーが出ます ちなみに%dでとればいいのでしょうがscanfは変なエラーでるときが多いので 嫌いなので使いたくありません 悩んだ挙句こうしてみましたが _getts(Word); if( "1"<= nunber && "11" >= nunber ){ number = atoi(Word); brerk; }; これでもエラーが出ます 1文字1文字for文で回して数字かどうか判定してあげるしかないのでしょうか? すっきりした書き方があればよろしくお願いします

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★strtol() 関数を使ってみる。 ・この関数ならば文字列を整数に変換する以外に数字文字列以外はエラーもチェックできます。  下にサンプルを載せます。 サンプル: #include <stdio.h> #include <stdlib.h> #include <errno.h> char buff[ 64 ]; char *check; long number; ←ナンバーはnu[m]berです。 while ( fgets(buff,sizeof(buff),stdin) != NULL ){  number = strtol( buff, &check, 10 );    if ( errno == ERANGE ){   puts( "number が長整数の範囲を超えました。" );  }  else if ( *check != '\0' ){   puts( "数字文字列ではありません。" );  }  else if ( (number >= 1) && (number <= 3) ){   printf( "入力した数は %d です。\n", number );  } } 解説: ・fgets() 関数で文字列を入力します。  その後、strtol() 関数で文字列を整数に変換しています。→atoi() の代わり  そして、グローバル変数の errno の値を調べます。この errno に ERANGE 定数が  セットされていると long 値を越える大きい(小さい)数字文字列ですのでエラーと  します。ERANGE 定数がセットされていない場合は check の位置が NULL 文字ならば  すべて数字文字列であったと判定します。少しでも英字や記号が含まれていると NULL  文字以外になるため、ここで数字文字列以外のエラーを表示します。 ・上記のを踏まえてプログラミングの参考にして下さい。 ・以上。おわり。→下の『参考URL』もどうぞ。

参考URL:
http://www9.plala.or.jp/sgwr-t/lib/strtol.html
KENMISE
質問者

お礼

まだまだ勉強不足でした *check != '\0' これは文字列の後につく終端コードですよね 数字には入らないと考えてよろしいのでしょうか やはり文字を1文字づつ回してあげるのがベストなようですね 勉強になるURLまでありがとうございました ---------------------------------------------------------------------- 文字列 s を、baseで指定された基数でlong型に変換し返却します。このとき、文字列中に変換不可能な文字があった場合には、その文字列のポインタをendptrに格納します。 atol関数は、単に文字列を10進のlong型変数に変換するのみで、文字列中に変換不可能な文字があったときには対応できませんが、strtolを使うと、変換可能な部分についてはきちんと変換し、変換不可能な部分についても情報を得ることができます。更に、baseを指定することにより、好きな基数で変換することができます。

その他の回答 (1)

回答No.1

目的はこういうことでしょうか? #include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { int n; char buffer[32]; gets_s(buffer, sizeof(buffer)); n = atoi(buffer); if(n >= 1 && n <= 3) { puts("1 - 3 です。"); } else { puts("1 - 3 ではありません。"); } } > とするとnunberの中に1~11が入るはずですが 申し訳ありませんが意味がわかりません。プログラムだけみると1~11が入るとは思えませんのでそう思われる根拠はなんでしょうか。 > ちなみに%dでとればいいのでしょうがscanfは変なエラーでるときが多いので 適切に使用し、適切な処理を行えば変なエラーはでません。 > if( "1"<= nunber && "11" >= nunber ){ "1"は、コンスタントプール"1"のアドレスとnunberの値(初期化されていない値)を比較しています。 "11"にしても同様です。 "1"は文字列(キャラクタ配列)。'1'はキャラクタ。1は数値。 違いを理解されておりますでしょうか。 文字列はstrcmpとかで比較しましょう。

KENMISE
質問者

お礼

>適切に使用し、適切な処理を行えば変なエラーはでません。 そうなのですか・・・ _tscanf_s(_T(""))でマルチコードにも対応するようにしたのですが まだまだ勉強不足なので使えないものとばかり思ってました "1"< <"11" はアスキーコードに変換して考えるといけるかなと思ったのですが そもそもstrcpyって便利ですね覚えておきます マルチコードだと_tcscpyですね

関連するQ&A

専門家に質問してみよう