2017-06-08 40 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