Reputation:
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
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
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