2017-06-08 42 views
-2

我目前正在參加CS50課程,而且我被困在信用問題上。這個想法是製作一個程序來驗證卡,因爲它們的內置校驗和。第一步是取每一位數字並乘以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; 
    } 
    } 
} 

我知道第一部分遠非完美,但它是目前我關心的校驗和功能。當它需要第二個數字(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 *卡; scanf(「%s」,卡片);'帶'char卡片[20]; scanf(「%s」,卡片);' –

回答

0

您可能以ASCII格式讀取字符串,即一系列字符。所以你的輸入"1500150015001500"實際上是一個由字符串終止字符0x0終止的字符序列,例如像{ '1', '5', '0', .... '\0' }。單個字符值(如'1')解釋爲整數值時,其ASCII碼爲'0'爲48,'1'爲49,'5'爲53。因此,像char c = '5'; int digit = c*2這樣的表達式實際上產生了106的digit。要將字符'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
  2. 在你的函數checksum,您需要將字符將字符串card中讀入數字轉換。如果系統中的字符集是ASCII,則可以通過從字符串中的每個字符中減去值0x30(即字符'0'的數值),然後對其進行算術運算來實現。
  3. char number[20]中的函數簽名是毫無意義的;有關更多信息,請參閱this question。由於當數組作爲函數參數傳遞時,數組衰減爲指向其第一個元素的指針,所以函數簽名中最好有char *number