user10621144
user10621144

Reputation:

Program stuck at scanf

so basically I'm trying to write a program as an exercise from my textbook where the user inputs a 12 digits number, and after a series of operations, a "check digits" gets printed out. Here is my code.

#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;
}

The problem is that the program outputs absolutely nothing and it never seems to go past the scanf as I'm always able to add more digits even after inputting the 12 initial ones and hitting enter. I don't even get any warnings or errors whatsoever. What am I doing wrong?

Upvotes: 1

Views: 891

Answers (2)

Aniket
Aniket

Reputation: 459

Since your scanf is using %d%d%d%d%d%d%d%d%d%d%d%d. It is expecting 12 numbers. So if you typed in 123456789012, the program scan in just 1 number. It reads 123456789012 not how you want it where one = 1, then two = 2 etc.

You can solve this by changing your scanf to:

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 will read a single digit. So now it will do what you want it to, where one = 1, then two = 2 etc.

Another way to solve this would be reading the number as a string. The convert the string into an int array. I've provided the code for how to do that below.

#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);
}

Upvotes: 1

chux
chux

Reputation: 154218

What am I doing wrong?

OP wants to read a 12 digit code, yet scanf("%d%d%d%d%d%d%d%d%d%d%d%d"... looks for 12 separate int.

@user3386109 well suggested using "%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d" to limit the length of each int to 1 digit.


Alternative:

As EAN can vary in length up to 18 digits, consider

#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
    }
  }
}

Upvotes: 1

Related Questions