質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.57%

C++ クラスについて

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 706

amareno

score 20

 実現したいこと

現在try throw catchとクラスを用いてパスワード認識のプログラムをC++で作っています。
下記のようにエラーが発生します。
私のコードのどこがおかしいか教えていただけますでしょうか?

 発生している問題・エラーメッセージ

Enter the password: 
buvuTGB3547&
Your password is not valid. 
libc++abi.dylib: terminating with uncaught exception of type double

Process finished with exit code 6

 該当のソースコード

#include <iostream>
#include <cstring>

using namespace std;

class PasswordError{
private:
    bool aUpper = false,
            aLower = false,
            aDigit = false,
            aPunct = false;

public:
    bool testNum(char pass[]) {

        for (int i = 0; pass[i]; ++i)
            if (isupper(pass[i]))
                aUpper = true;
            else if (islower(pass[i]))
                aLower = true;
            else if (isdigit(pass[i]))
                aDigit = true;
            else if (!ispunct(pass[i]))
                aPunct = true;
        if (aUpper && aLower && aDigit && aPunct)
            return true;
        else
            return false;
    }

    void exception() {
        try {
            if (!aUpper)
                throw 2;
        }

        catch (int a) {
            cout << "Your password should contain at least one upper case" << endl;
        }

        try {
            if (!aLower)
                throw 4.5;
        }

        catch (double b) {
            cout << "Your password should contain at least one lower case" << endl;
        }

        try {
            if (!aDigit)
                throw 'c';
        }

        catch (char c) {
            cout << "Your password should contain at least one numeric digit" << endl;
        }

        try {
            if (!aPunct)
                throw 1.5f;
        }

        catch (float d) {
            cout << "Your password should contain at least one of these special characters: !@#$%&*:;" << endl;
        }
    }
};

int main() {
    PasswordError passw;

    const int SIZE = 100;
    char password[SIZE];

    cout << "Enter the password: " << endl;
    cin.getline(password, SIZE);


    try {
        if (strlen(password) < 8) {
            throw 4;
        }
    }

    catch (int i) {
        cout << " Your password must be at least 8 characters long." << endl;
    }


    if (passw.testNum(password))
        cout << "Your password is valid." << endl;
    else {
        cout << "Your password is not valid. " << endl;
        passw.exception();

        return 0;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

try {
     if (!aPunct)
         throw 1.5;
}
catch (float d) {
     cout << "Your password should contain at least one of these special characters: !@#$%&*:;" << endl;
}

単に1.5と書いてしまうと、double型のリテラルと見做されます。1.5fと書いてください。

ところで、これ例外を利用する意味はあるんです?

コメントを受けて

例外を利用せよ、ってのはおそらくそういう意味では無いです。
ついでに判定処理も手直しして書いてみました。

#include <algorithm>
#include <cstring>
#include <iostream>
#include <string>

class Password {
public:
    Password(const std::string& p) {
        using namespace std::literals::string_literals;

        if(p.size() < 8) {
            throw "Your password must be at least 8 characters long."s;
        }
        if(!std::any_of(std::cbegin(p), std::cend(p), ::isupper)) {
            throw "Your password should contain at least one upper case."s;
        }
        if(!std::any_of(std::cbegin(p), std::cend(p), ::islower)) {
            throw "Your password should contain at least one lower case."s;
        }
        if(!std::any_of(std::cbegin(p), std::cend(p), ::isdigit)) {
            throw "Your password should contain at least one numeric digit."s;
        }
        if(!std::any_of(std::cbegin(p), std::cend(p), ::ispunct)) {
            throw "Your password should contain at least one of these special characters: !@#$%&*:; ."s;
        }
    }
};

int main() {
    try {
        Password password{"buvuTGB3547&"};
        std::cout << "Your password is valid.\n";
    }
    catch(const std::string& e_message) {
        std::cerr << "Your password is not valid.\n" << e_message << "\n";
    }
}

何かしら見落としや不勉強があるかもしれません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/09 18:24

    すいません、testNumの中に例外を入れてそれをmain関数で呼び出すという意味でしょうか? もしよろしければ、もうすこし詳しく説明して頂けないでしょうか?

    キャンセル

  • 2018/11/09 18:30

    追記しました。

    キャンセル

  • 2018/11/09 18:54

    ありがとうございます。コードを解読するのが難しそうですが、自分のコードと照らし合わせて頑張ってみます。

    キャンセル

0

単に1.5と書いた場合、それはdouble型の値となります。throw 1.5;catch(float e)では回収できません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/09 18:08

    なるほど、回答ありがとうございます。訂正します。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る