エラー表示+再入力

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
みん

エラー表示+再入力

#1

投稿記事 by みん » 17年前

質問をさせていただきます。
下のプログラムを数字以外がでると
再入力させたいのですが、isdigitでうまくできません。
ifで判定処理をするのにはどのようにしたら
よいのでしょうか。すみませんが
おしえてください。
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

/*猫の定義*/
class Neko
{
private:
string name; //名前
public:
Neko(string); //コンストラクタ
void naku() const;
};

Neko::Neko(string s) : name(s){}

void Neko::naku() const{
cout << "にゃあ。私は" << name << "だ。" << endl;
}

/*猫の稼ぎの定義*/
class SalaryNeko : public Neko
{
private:
int gekkyu; //月給
public:
SalaryNeko(string, int); //コンストラクタ

int get_nensyu() const { return gekkyu * 12; }//年収を戻す関数

void syoukyu() { gekkyu++; } //月給を増やす関数

int get_gekkyu() const{ return gekkyu; }//月給の値を戻す関数
};

SalaryNeko::SalaryNeko(string s, int x) : Neko(s), gekkyu(x){} //コンストラクタ

/*猫の派生クラス*/
class SalaryNekoWithBonus :public SalaryNeko
{
private:
int bonus; //ボーナス
public:
//コンストラクタ
//第1引数が名前、第2引数が月給、第3引数がボーナスを表す
SalaryNekoWithBonus(string, int, int);
//年収を戻す関数
int get_nensyu() const{return get_gekkyu() * (12 + bonus);}
};

SalaryNekoWithBonus::SalaryNekoWithBonus(string s, int g, int b) : SalaryNeko(s, g), bonus(b){}

/*メイン*/
int main()
{
string name; //名前の一時格納場所
int gekkyu; //月給
int bonus; //ボーナスが月給の何ヶ月分か
cout << "金稼ぎ猫・ボーナスを生成します。\n名前を決めて入力してください。" << endl;

cin >> name;
cout << "月給を決めて入力してください。(1万円単位)" << endl;
cout << "(数字は半角で入力してください。)" << endl;
cin >> gekkyu;
if(isdigit==0){
cout << "エラー";
}
cout << "ボーナスは月給の何ヶ月分か、入力してください。" << endl;
cin >> bonus;
SalaryNekoWithBonus dora(name, gekkyu, bonus); //サラリー猫・ウイズ・ボーナスの生成

while(1)
{
//動作内容入力処理
int ans;
cout << "どうしますか?" << endl;
cout << "1 鳴かす 2 年収を表示 3 昇給 4 やめる"<<endl;
cin >> ans;

//動作内容判定処理
if(ans == 1)
{
dora.naku();
}
else if(ans == 2)
{
//2 年収を表示
cout << "年収は現在" << dora.get_nensyu() << "です。" << endl;
}
else if(ans == 3)
{
dora.syoukyu();
cout << "1万円昇給しました。" << endl;
}
/*else if(ans<1 && ans>4)
{
cout << " 数値が異常です.再入力してください";
}*/
else if(ans == 4)
{
break;
}

cout << endl;
}
cout << "おわり" << endl;
}

みん

Re:エラー表示+再入力

#2

投稿記事 by みん » 17年前

すみません。こちらはC++です

keichan

Re:エラー表示+再入力

#3

投稿記事 by keichan » 17年前

isdigitは標準"関数"ですから
if( isdigit == 0 )
と書くと「isdigitのアドレスが0番地であるか評価する」になります。
当然0番地に配置される事はあり得ませんので"エラー"と表示することはありません。

また isdigit は指定した'一文字'が数値であるかどうかをチェックする関数ですので
2桁以上の文字を入力したときにちゃんとエラーチェックできません。
例)月給を決めて入力してください -> 1a
上記例だとスルーされる可能性があるということです。

C++ですので、私であればこう書くかな(要BOOSTインストール)

#include <boost/lexical_cast.hpp>

std::string gekkyu_buf;
while(1)
{
cin >> gekkyu_buf;
try {
gekkyu = boost::lexical_cast<int>(gekkyu);
break;
} catch( boost::bad_lexical_cast& ) {
std::cout << "エラー" << std::endl;
}
}

keichan

Re:エラー表示+再入力

#4

投稿記事 by keichan » 17年前

typo

× gekkyu = boost::lexical_cast<int>(gekkyu);
        ↓
○ gekkyu = boost::lexical_cast<int>(gekkyu_buf);

Justy

Re:エラー表示+再入力

#5

投稿記事 by Justy » 17年前

  boostが入ってるなら spiritでもいいかも。
[color=#d0d0ff" face="monospace]#include <boost/spirit/core.hpp>
#include <boost/spirit/phoenix/primitives.hpp>
#include <boost/spirit/phoenix/operators.hpp>
#include <iostream>
#include <string>
using namespace boost::spirit;
using namespace phoenix;

int main()
{
    std::string gekkyu_buf; 
    std::cin >> gekkyu_buf; 
    int n;
    if(parse(gekkyu_buf.begin(), gekkyu_buf.end(), int_p[var(n) = arg1], space_p).full)
        std::cout << "整数 " << n << std::endl;
    else
        std::cout << "整数以外が入力された " << std::endl;
    return 0;
}[/color]

Justy

Re:エラー表示+再入力

#6

投稿記事 by Justy » 17年前

 boostがないのならこういう感じで数字かどうか、というより数値に正しく代入できたかどうかが確認できます。
[color=#d0d0ff" face="monospace]    int n;
    std::cin >> n; 
    if(!std::cin.fail())
        std::cout << "n = " << n << std::endl;
    else
        std::cout << "error"<< std::endl;
[/color]

みん

Re:エラー表示+再入力

#7

投稿記事 by みん » 17年前

ありがとうございます。
皆様のおかげで無事解決できました。

閉鎖

“C言語何でも質問掲示板” へ戻る