程序卡在scanf

时间:2018-11-10 01:12:28

标签: c

因此,基本上,我试图从我的课本中编写一个程序作为练习,其中用户输入12位数字,并且在一系列操作之后,打印出“校验位”。这是我的代码。

#include <stdio.h>

int main(){
  int one = 0, two = 0, three = 0, four = 0, five = 0, six = 0, seven = 0,
      eight = 0, nine = 0, ten = 0, eleven = 0, twelve = 0;
  int check_digit;

  printf("Enter the first 12 digits of an EAN: ");
  scanf("%d%d%d%d%d%d%d%d%d%d%d%d", &one, &two, &three, &four, &five, &six, &seven, 
                                    &eight, &nine, &ten, &eleven, &twelve);

  check_digit = 9 - (((two + four + six + eight + ten + twelve)*3 +
            (one + three + five + seven + nine + eleven))-1)%10;

  printf("Check digit: %d\n\n", check_digit);

  return 0;
}

问题在于程序绝对不会输出任何内容,并且似乎永远不会超出scanf,因为即使输入了12个初始数字并按回车键,我也总是能够添加更多数字。我什至没有收到任何警告或错误。 我在做什么错了?

2 个答案:

答案 0 :(得分:1)

由于您的scanf正在使用%d%d%d%d%d%d%d%d%d%d%d%d。预计有12个数字。因此,如果您输入123456789012,程序将仅扫描1个数字。它在123456789012处而不是在one = 1等处读取two = 2,而不是您想要的样子。

您可以通过将scanf更改为:

scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d", &one, &two, &three, &four, &five, &six, &seven, &eight, &nine, &ten, &eleven, &twelve);

%1d将读取一位数字。因此,现在它将执行您想要的操作,在one = 1,然后在two = 2等位置。

解决此问题的另一种方法是将数字读取为字符串。将字符串转换为int数组。我在下面提供了如何执行此操作的代码。

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE        12

// Function prototypes
void str_arr_to_int_arr(char str[], int num[], int len);
int check_digit(int EAN[], int len);

int main(void) {

    char EAN_str[MAX_SIZE + 1];
    int EAN_int[MAX_SIZE + 1];

    printf("Enter the first 12 digits of an EAN: ");
    scanf("%12s", EAN_str);

    str_arr_to_int_arr(EAN_str, EAN_int, MAX_SIZE);

    int answer = check_digit(EAN_int, MAX_SIZE);

    printf("Check digit: %d\n", answer);

    return 0;
}

// This function will convert a char array into an int array
void str_arr_to_int_arr(char str[], int num[], int len) {

    int i = 0;
    while (i < len) {

        if (str[i] >= '0' && str[i] <= '9') {
            num[i] = str[i] - '0';
        } else {
            printf("ERROR: You entered a non-number\n");
            exit(1);
        }

        i++;
    }

}

// Does the check_digit formula on an EAN
int check_digit(int EAN[], int len) {

    int sum_pos = 0;
    int sum_neg = 0;

    int i = 0;
    while (i < len) {

        if (i % 2 == 0) {
            sum_pos += EAN[i];
        } else {
            sum_neg += EAN[i];
        }

        i++;
    }

    return (9 - (((sum_pos * 3) + sum_neg) - 1) % 10);
}

答案 1 :(得分:1)

  

我在做什么错了?

OP希望读取12位数字的代码,但是scanf("%d%d%d%d%d%d%d%d%d%d%d%d"...查找12个单独的int

@user3386109建议使用"%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d"将每个int的长度限制为1位数字。


替代:

EAN的长度最多可以变化18位数字,请考虑

#define EAN_N 18
char buf[2*EAN_N];  // extra for \n, \0 and other other characters.
if (fgets(buf, sizof buf, stdin)) {
  int n = 0;
  while (buf[n] >= '0' && buf[n] <= '9') n++;
  if (buf[n] == '\n' || buf[n] == '\0' && <= EAN_N) {
    switch (n) {
       case 12: 
         // OP's original code
         break;
       case TBD: 
         // handle of cases TBD
    }
  }
}