2016-10-12 13 views
-2

今年はCS50クラスに続いて、C(およびすべてのプログラミングの形式)を完全に新しくしました。私は、Luhnのアルゴリズムを使ってクレジットカード番号の有効性をテストする簡単なプログラムを書くのは本当に苦労しています。Cでプログラムを書いて、Luhnのアルゴリズムをクレジットカードの有効性確認に適用します。

私のプログラムでは、入力がクレジットカード形式(例:負の数や文字など)に従わない場合にユーザーに入力と再入力を促し、アルゴリズムをその番号が有効なクレジットカード番号かどうかを確認し、有効な場合は、Visa、MasterCard、またはAmExのいずれであるかを確認します。

私は、このウェブサイト上で異なるコードで回答されていることを知っています。私はこのサイトとネット上の他の場所で私が見つけた可能性のあるものすべてを読むことを誓いますが、 Cの構文と私は私が他の答えから理解できないコードのビットをコピーするのではなく、私自身何かを思いついてみようと思った。誰かが私を助けて、これまでに行ったことを見て、私が間違っていることを教えてくれたら、本当に感謝しています。また、Cの構文ロジックをよりよく理解するのに役立つヒントは非常に高く評価されています。私は全く新しい初心者です(3週間、自己ペースでプログラミングを勉強しています...)。

私のプログラムはコンパイルされていますが、実行すると非常に奇妙な方法で動作します。入力を入力すると、(有効な数値であっても)無効であると表示されることがあります。私がEnterキーを押した後の何かは、何度もReturnキーを押しても実行を停止しません。ここで

は、これまでの私のコードです:

#include <stdio.h> 
#include <cs50.h> 
#include <math.h> 

int main(void) 
{ 
    printf("Please give me your credit card number:\n") ; 

    long long card_num ; 

    do 
    { 
     card_num = GetLongLong() ; 
    } 
    while (card_num < 1 || card_num > 9999999999999999) ; 

    // Make a copy of the card number to be used and modified throughout the process. 

    long long temp_num = card_num ; 
    int digit = 0 ; 
    int count = 0 ; 
    int sum_a = 0 ; 
    int sum_b = 0 ; 

    // Isolate every digit from the credit card number using a loop and the variable 'digit'. 
    // Keep track of the amount and position of each digit using variable 'count'. 

    while (card_num >= 0) 
    { 
     digit = card_num % 10 ; 
     count++ ; 
     temp_num = (card_num - digit)/10 ; 
     break ; 


    // Apply Luhn's algorithm using two different 'for' loops depending on the position of each digit. 

     for (count = 0 ; count % 2 == 0 ; count++) 
     { 
      sum_a = sum_a + ((card_num % 10) * 2) ; 

      while ((card_num % 10) * 2 >= 10) 
      { 
       sum_a = (sum_a % 10) + 1 ; 
      } 
     } 

     for (count = 0 ; count % 2 != 0 ; count++) 
     { 
      sum_b = sum_b + digit ; 
     } 

     return sum_a ; 
     return sum_b ; 
     return count ; 
    } 

    // Checking the validity of the number according to Luhn's algorithm 

    int total_sum = sum_a + sum_b ; 

    if (total_sum % 10 != 0) 
    { 
     printf("This is an invalid number.\n") ; 
    } 

// If the number entered doesn't have the right amount of digits according 
// to variable 'count', declare the number as invalid. 

    if (count != 13 || count != 15 || count != 16) 
    { 
     printf("This is an invalid number.\n") ; 
    } 

// Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits. 
// Store the results in a variable 'company_id'. 

    temp_num = card_num ; 
    int company_id ; 

    while (temp_num > 100) 
    { 
     temp_num = card_num - (card_num % 10) ; 
     company_id = temp_num/10 ; 
    } 

    return company_id ; 

// Print the type of credit card depending on the company ID and amount of digits. 

    if (company_id > 50 && company_id < 56 && count == 16) 
    { 
     printf("MASTERCARD\n") ; 
    } 
    else if ((company_id == 4) && (count == 13 || count == 16)) 
    { 
     printf("VISA\n") ; 
    } 
    else if ((company_id == 34 || company_id == 37) && (count == 15)) 
    { 
     printf("AMEX\n") ; 
    } 
    else 
    { 
     printf("This is an invalid number.\n") ; 
    } 

    return 0 ; 

} 
+2

あなたはそのブレークに条件なしで 'while'の中で' break'を使いました。それは毎回発生します。だからあなたのwhileループは多くても1より多くループしません。 – galfisher

+0

'GetLongLong()'の実装はどこですか? – galfisher

+0

入力を数字に変換する代わりに文字列としてカード番号を入力し、文字列に(効果的に)戻って各桁を調べる方が簡単かもしれません。おそらく、「長いカード番号」内のさまざまなフィールドは、ある段階で2進数に変換する必要があります。文字列からこれらのフィールドを簡単に抽出できるときは、後でお勧めします。 –

答えて

0

あなたの答えは、以前から、論理的に従っていないセクションで注文模倣作品のうちです。

具体的な問題:

このロジック:

if (count != 13 || count != 15 || count != 16) 

これが機能するため S(& &)でなければなりませんまたは S(||)、すべてのカードを無効にします。

このループは意味がありません:それはループを抜けて、次の20行を無視しますので

while (card_num >= 0) 
{ 
    digit = card_num % 10 ; 
    count++ ; 
    temp_num = (card_num - digit)/10 ; 
    break ; 
    ... 
} 

breakは無条件です。いくつかの場所では

return sum_a ; 
return sum_b ; 
return count ; 
return company_id ; 
return 0 ; 

あなたがtemp_numを使用する必要があるときにcard_numを使用する:あなたが有効であるだけで、最後のそのreturn 5回、呼び出すよう

あなたが他の場所からサブルーチンにスプライシングされているように見えます。

カードが無効であることがわかったらプログラムを終了することはできません。代わりにテストを続けるだけです。あなたは、カードが有効であることを確認することができません。

カード番号の桁数を数えますが、その桁数が有効かどうかをテストする前に、他のチェックを実行するまで待機します。

以下は上記といくつかのスタイルの問題に対処するために、あなたのコードの私のリワークです:

#include <stdio.h> 
#include <cs50.h> 
#include <math.h> 

int main(void) 
{ 
    printf("Please give me your credit card number: ") ; 

    long long card_num = 0LL; 

    while (card_num < 1LL || card_num > 9999999999999999LL) 
    { 
     card_num = GetLongLong(); 
    } 

    // Make a copy of the card number to be used and modified throughout the process. 

    long long temp_num = card_num; 

    // Isolate every digit from the credit card number using a loop and the variable 'digit'. 
    // Keep track of the amount and position of each digit using variable 'count'. 

    int count = 0; 

    while (temp_num > 0LL) 
    { 
     temp_num = temp_num/10LL; 
     count++; 
    } 

    // If the number entered doesn't have the right amount of digits according 
    // to variable 'count', declare the number as invalid. 

    if (count != 13 && count != 15 && count != 16) 
    { 
     printf("This is an invalid number (# of digits).\n"); 
     return 1; 
    } 

    // Reset value of variable 'temp_num' and apply calculations that will isolate the first two digits. 
    // Store the results in a variable 'company_id'. 

    temp_num = card_num; 

    while (temp_num > 100LL) 
    { 
     temp_num = temp_num/10LL; 
    } 

    int company_id = temp_num; 

    // Print the type of credit card depending on the company ID and amount of digits. 

    if (company_id > 50 && company_id < 56 && count == 16) 
    { 
     printf("MASTERCARD\n") ; 
    } 
    else if ((company_id == 34 || company_id == 37) && (count == 15)) 
    { 
     printf("AMEX\n") ; 
    } 
    else if ((company_id/10 == 4) && (count == 13 || count == 16 || count == 19)) 
    { 
     printf("VISA\n") ; 
    } 
    else 
    { 
     printf("This card was issued by an unknown company.\n"); 
    } 

    // Apply Luhn's algorithm. 

    int sum = 0; 

    temp_num = card_num; 

    for (int i = 1; i <= count; i++) 
    { 
     int digit = temp_num % 10LL; 

     if (i % 2 == 0) 
     { 
      digit *= 2; 

      if (digit > 9) 
      { 
       digit -= 9; 
      } 
     } 

     sum += digit; 

     temp_num /= 10LL; 
    } 

    // Checking the validity of the number according to Luhn's algorithm 

    if (sum % 10 != 0) 
    { 
     printf("This is an invalid number (Luhn's algorithm).\n"); 
     return 1; 
    } 

    printf("This is a valid number.\n"); 

    return 0; 
} 

これは、完成したプログラムではありません - エラーチェックと必要なその他の詳細があります。 2倍のカード番号が9より大きいときに数字を合計するのではなく、9を減算するより簡単な方法を使用しました。

+0

うわー、これはとても役に立ちます。私は実際に投稿した後にコードを再編集し、ブレークとリターンを取り除きましたが、プログラムの動作の仕方に変化は見られず、ループの何が間違っているのか理解できませんでした。修正して修正します。説明していただきありがとうございます。 – Mynah

関連する問題