-1

最近C++を開始し、構文を理解しようとしていますが、配置に問題があります。有効なクレジットカードを要求するクレジットカード検証機能を実行してから、クレジットカードの種類を印刷する必要があります。

私の唯一の問題は、クレジットカードの種類を決定するためのifステートメントにあります。正確にどこに配置するのか、角かっこなどがないかどうかはわかりません。

私にとって問題となる正確なチャンクは次のとおりです。

        if(c.substr(0, 2) == "65" || c.substr(0, 5) == "6011" || c.substr(0, 7) >= "622126" && c.substr(0, 7) <= "622925" || c.substr(0, 4) >= "644" && c.substr(0, 4) <= "649")
            s = "You have a Discover card";
        if(c.substr(0, 2) >= "51" && c.substr(0, 2) <= "55")
            s = "You have a MasterCard card";
        if(c.substr(0, 1) == "4")
            s = "You have a Visa card";
        if(c.substr(0, 2) == "34" || c.substr(0, 2) == "37")
            s = "You have an American Express card"; 

これは私のコードです。

#include <iostream>
#include <string>
using namespace std;

void validateCC();
string checkCC(string, int, bool&);
bool validateCCNum(string);

void main() {
    char again;
    cout << "Validate a credit card number (Y/N)? ";
    cin >> again;
    while (toupper(again) == 'Y') {
        validateCC();
        cout << "Validate a credit card number (Y/N)? ";
        cin >> again;
    }
}

void validateCC() {
    string ccn, msg;
    bool OK;
    int ccLen;
    cout << "Please enter a 15 or 16 digit credit card number."
        << "\n(No spaces or hyphens): ";
    cin >> ccn;
    ccLen = ccn.length();
    msg = checkCC(ccn, ccLen, OK);
    if(!OK)
        cout << msg;
    else
        if(validateCCNum(ccn))
            cout << "Valid credit card number\n";
        else
            cout << "Invalid credit card number\n";
    cout << "\n" << endl;
}

string checkCC(string c, int cLen, bool& ccOK) {
    string s = "";
    ccOK = true;
    for(int i=0;i<cLen && ccOK;++i)
        ccOK = isdigit(c[i]);

        if(c.substr(0, 2) == "65" || c.substr(0, 5) == "6011" || c.substr(0, 7) >= "622126" && c.substr(0, 7) <= "622925" || c.substr(0, 4) >= "644" && c.substr(0, 4) <= "649")
            s = "You have a Discover card";
        if(c.substr(0, 2) >= "51" && c.substr(0, 2) <= "55")
            s = "You have a MasterCard card";
        if(c.substr(0, 1) == "4")
            s = "You have a Visa card";
        if(c.substr(0, 2) == "34" || c.substr(0, 2) == "37")
            s = "You have an American Express card"; 

    if(ccOK == false) {
        s = "Invalid credit card number digits";
    } else if(cLen == 15) {
        if(c.substr(0, 2) != "34" && c.substr(0, 2) != "37") {
            ccOK = false;
            s = "Invalid American Express credit card number";
        }
    } else if(cLen != 16) {
        ccOK = false;
        s = "Invalid credit card number length";
    }
    return s;
}

bool validateCCNum(string cc) {
    bool flip = true;
    int tmp, num = 0;
    int ccLen = cc.length()-1;
    for(int ndx=ccLen;ndx>=0;ndx--) {
            if(flip)
                num += cc[ndx] - '0';
            else {
                tmp = (cc[ndx] - '0') * 2;
                if(tmp <= 9)
                    num += tmp;
                else
                    num += (1 + (tmp - 10)); // max of 18
            }
            flip = !flip;
    }
    return num % 10 == 0;
}

問題のあるチャンクが現在の場所に属しているのか、それともvalidateCC()セクションに配置してパラメーターを追加したのかわかりません。

ありがとうございました。

4

4 に答える 4

1

<=> =などを評価できるように、部分文字列をint(stringVar >> IntVar;)に変更してみてください。

    #include <iostream>
#include <string>
using namespace std;

void validateCC();
string checkCC(string, int, bool&);
bool validateCCNum(string);

void main() {
    char again;
    cout << "Validate a credit card number (Y/N)? ";
    cin >> again;
    while (toupper(again) == 'Y') {
        validateCC();
        cout << "Validate a credit card number (Y/N)? ";
        cin >> again;
    }
}
string checkCardType(string c){
if(atoi(c.substr(0, 2).c_str()) == 65 || atoi(c.substr(0, 5).c_str()) == 6011 || atoi(c.substr(0, 7).c_str()) >= 622126 && atoi(c.substr(0, 7).c_str()) <= 622925 || atoi(c.substr(0, 4).c_str()) >= 644 && atoi(c.substr(0, 4).c_str()) <= 649)
            return "You have a Discover card";
        if(atoi(c.substr(0, 2).c_str()) >= 51 && atoi(c.substr(0, 2).c_str()) <= 55)
            return "You have a MasterCard card";
        if(atoi(c.substr(0, 1).c_str()) == 4)
            return "You have a Visa card";
        if(atoi(c.substr(0, 2).c_str()) == 34 || atoi(c.substr(0, 2).c_str()) == 37)
            return "You have an American Express card"; 
        return "Card not recognized";
}
void validateCC() {
    string ccn, msg;
    bool OK;
    int ccLen;
    cout << "Please enter a 15 or 16 digit credit card number."
        << "\n(No spaces or hyphens): ";
    cin >> ccn;
    ccLen = ccn.length();
    msg = checkCC(ccn, ccLen, OK);
    if(!OK)
        cout << msg;
    else
        if(validateCCNum(ccn)){
            cout << "Valid credit card number\n";
            cout << checkCardType(ccn);}
        else
            cout << "Invalid credit card number\n";
    cout << "\n" << endl;
}

string checkCC(string c, int cLen, bool& ccOK) {
    string s = "";
    ccOK = true;
    for(int i=0;i<cLen && ccOK;++i)
        ccOK = isdigit(c[i]);

    if(ccOK == false) {
        s = "Invalid credit card number digits";
    } else if(cLen == 15) {
        if(c.substr(0, 2) != "34" && c.substr(0, 2) != "37") {
            ccOK = false;
            s = "Invalid American Express credit card number";
        }
    } else if(cLen != 16) {
        ccOK = false;
        s = "Invalid credit card number length";
    }
    return s;
}

bool validateCCNum(string cc) {
    bool flip = true;
    int tmp, num = 0;
    int ccLen = cc.length()-1;
    for(int ndx=ccLen;ndx>=0;ndx--) {
            if(flip)
                num += cc[ndx] - '0';
            else {
                tmp = (cc[ndx] - '0') * 2;
                if(tmp <= 9)
                    num += tmp;
                else
                    num += (1 + (tmp - 10)); // max of 18
            }
            flip = !flip;
    }
    return num % 10 == 0;
}
于 2013-01-13T22:42:40.197 に答える
0

それを行う最も効果的な方法ではありませんが、コードに見られる唯一の問題は、場合によっては文字数が多すぎることc.substr(0, 5) == "6011"ですc.size() == 4

価値があるので、プレフィックスをとして宣言し、それらstatic std::string constに使用std::equalします(最初に番号が十分に長いことを確認した後)。または、最初の文字のスイッチを使用します。

switch (c[0])
{
case '6':
    //  Additional tests for Discover...
    break;
case '5':
    //  Additional tests for MasterCard...
    break;

case '4':
    //  Additional tests for Visa...
    break;

case '3':
    //  Additional tests for American express..
    break;
}

または、さらに可能性が高いのは、構成ファイルから読み取ったパターンで正規表現を使用することです。これは、プログラムにハードコーディングするタイプの情報ではありません。

于 2013-01-13T23:04:06.833 に答える
0

このstd::string::substrメソッドは文字列を返します。これは別の文字列と比較できます。これまでのところ、コードは正常に見えます。

角かっこを使用する場合は、C++演算子の優先順位を参照してください。コードを理解しているので、if条件に角かっこは必要ありません。ただし、疑問がある場合は、意図を明確にするために角かっこを使用してください。

checkCCクレジットカード番号の長さは、それ自体で判断できるため、渡す必要はありません。また、クレジットカード番号を次のように渡します

string checkCC(const string &c, ...)

これは文字列のコピーを回避するためです。

于 2013-01-13T23:05:05.070 に答える
0

これが機能するかどうかはよくわかりません。

c.substr(0、2)== "34"

文字列を整数(atoi)に解析してから、「==」と比較してみませんか。また、文字列は "string" .compare( "string2")(同じ文字列の場合は0を返します)と比較されます。

于 2013-01-13T22:55:17.683 に答える