令人困惑的字符串交互

时间:2017-06-08 20:45:28

标签: c char cs50

我目前正在做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

2 个答案:

答案 0 :(得分:0)

有几件事:

  1. char *card; scanf("%s", card);无效。您需要将card声明为固定大小的数组(即char card[20]),或使用malloc为指针char *card;分配内存。如果您选择后一个选项,则在完成后还需要在内存中使用free
  2. 在您的函数checksum中,您需要将字符串card中读取的字符转换为数字。如果系统上的字符集是ASCII,则可以通过从字符串中的每个字符中减去值0x30(即字符'0'的数值),然后对其执行算术来实现此目的。 / LI> 功能签名中的
  3. char number[20]毫无意义;有关详细信息,请参阅this question。由于数组在作为函数参数传递时衰减为指向其第一个元素的指针,因此您也可以在函数签名中使用char *number

答案 1 :(得分:0)

你读取一个字符串,即一系列字符,可能是ASCII格式。所以你的输入"1500150015001500"实际上是一个由字符串终止字符0x0终止的字符序列,例如比如{ '1', '5', '0', .... '\0' }。像'1'这样的单个字符值,当被解释为整数值时,由其ASCII代码表示,'0'为48,'1'为49,...,53为'5'。因此,像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;
    }
  }
}