2017-06-08 10 views
-2

私は現在CS50コースをやっていますが、私は信用問題に悩まされています。アイデアは、内蔵のチェックサムのためにカードを検証するプログラムを作ることです。最初のステップでは、2桁目ごとに2を掛けてから、すべての桁を一緒に加算します。混乱している文字列の相互作用

私のコードは完成していませんが、私は何が起こっているかを見ることができるようにいくつかの仲介ステップを印刷するように設定しました。

#include <stdio.h> 
#include <string.h> 

void checksum (char number[20]); 

int main (void){ 
    char *card; 

    printf("Please enter a card number:"); 
    scanf("%s", card); 
    if (strlen(card) == 13 || strlen(card) == 16 || strlen(card) == 15) { 
    checksum(card); 
    } 
    else{ 
    printf("Not a number. Please try again.\n"); 
    main(); 
    } 
} 

void checksum (char *number) { 

    int check = 0; 
    int digits = 0; 
    for(int i = 1; i < 17; i += 2){ 
    printf("No%c\n", number[i]); 
    digits = (number[i] * 2); 
    printf("D%i\n", digits); 
    while (digits > 0) { 
     check += digits % 10; 
     printf("C%i\n", check); 
     digits = digits/10; 
    } 
    } 
} 

最初の部分は完全ではありませんが、それは私が現時点で懸念しているチェックサム機能です。 2番目の数字(5)を取るときはすべて正常です。しかし、次の行で2を掛け合わせると、結果は106(?)

誰かがここで何が起こっているのか説明できますか?

terminal output

+1

あなたが乗算されているASCII文字(すなわち、テキスト)。最初に数値に変換します。 – kaylum

+0

[単一の文字をintに変換する方法](https://stackoverflow.com/questions/439573/how-to-convert-a-single-char-into-an-int)の可能な複製 – kaylum

+1

まず、 'char * card; scanf( "%s"、card); '' charカード[20]; scanf( "%s"、card); ' –

答えて

0

文字列、つまり一連の文字をASCII形式で読み込んでいます。だからあなたの入力"1500150015001500"は実際に文字0x0で終わる文字列で終わる文字列です。 { '1', '5', '0', .... '\0' }のように。 '1'のような1文字の値は、ASCIIコード('0'では48、では49、'5'では53)で表されます。したがって、char c = '5'; int digit = c*2のような式は、実際には、digitに対して106をもたらす。文字'5'を整数値5とするには、int digit = (c - '0')と書くことができます。これは、(53 - 48)と同じです。何が起こるか

くらいに自分のコードを変更せずに

、テスト:

#include <stdio.h> 
#include <string.h> 

void checksum (char *number); 

int main (void){ 
    char card[30]; 

    printf("Please enter a card number:"); 
    scanf("%s", card); 
    if (strlen(card) == 13 || strlen(card) == 16 || strlen(card) == 15) { 
    checksum(card); 
    } 
    else{ 
    printf("Not a number. Please try again.\n"); 
    main(); 
    } 
} 

void checksum (char *number) { 

    int check = 0; 
    int digits = 0; 
    for(int i = 1; i < strlen(number); i += 2){ 
    printf("No%c\n", number[i]); 
    digits = ((number[i]-'0') * 2); 
    printf("D%i\n", digits); 
    while (digits > 0) { 
     check += digits % 10; 
     printf("C%i\n", check); 
     digits = digits/10; 
    } 
    } 
} 
0

物事のカップル:

  1. char *card; scanf("%s", card);は仕事に行くのではありません。 cardを固定サイズの配列(つまりchar card[20])として宣言するか、またはmallocを使用してポインタchar *card;のメモリを割り当てる必要があります。後者のオプションを選択した場合は、完了したらメモリにfreeも使用する必要があります。あなたの関数checksum
  2. 、あなたは番号に文字列cardに読ん文字を変換する必要があります。システム上の文字セットがASCIIの場合は、演算を実行する前に文字列内の各文字から値0x30(つまり文字の数値'0')を減算することでこれを達成できます。
  3. char number[20]は、機能シグニチャでは無意味です。詳細については、this questionを参照してください。関数の引数として渡されると、配列は最初の要素へのポインタに減衰するので、関数シグネチャにはchar *numberがあるかもしれません。
関連する問題