Universal Product Code challenge

删除回忆录丶 提交于 2020-01-16 07:16:02

问题


I am curious how to correctly use %d in the C language. I am currently taking a course in C programming and we were given a small challenge to edit a code from the textbook (C Programming A Modern Approach, K. N. KING). The goal was to edit the code from three inputs of the bar code:

  • the 1st digit, the 5th, and the 5th to last into one single input, or
  • all 11 digits at once.

In the way the text explains the operator, I believe that %1d allows the entered integers to be individually assigned to the corresponding variable. Below is the edited code.

#include <stdio.h>

int main(void)
{

    /* 11 integers that come from the bar code of the product, 
    then 2 intermediate variables for calulation, and lastly the final answer.*/

    int d, i1, i2, i3, i4, i5, j1, j2, j3, j4, j5, first_sum, second_sum, total;    

    printf("Enter the 11 digit Universal Product Code: ");
    scanf("%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d%1d", &d, &i1, &i2, &i3, &i4, &i5, &j1, &j2, &j3, &j4, &j5);

    // The steps for each calculation from the textbook.
    first_sum = d + i2 + i4 + j1 + j3 + j5;
    second_sum = i1 + i3 + i5 + j2 + j4;
    total = 3 * first_sum + second_sum;

    // Prints check digit for given product code.
    printf("Check Digit: %d\n", 9 - ((total-1) % 10));
    return 0;
}

However when I run the program (same trouble with the original program) it does not accept the 11 digit input as 11 separate numbers, only as one large number. Instead it still requires enter to be hit after each integer. Can integers be read and assigned to variables this way?


回答1:


Given the code below, if you type "123" and then press enter, it will print "1 2 3".

int main( void )
{
    int a, b, c;

    printf( "Enter a three digit number\n" );
    if ( scanf( "%1d%1d%1d", &a, &b, &c ) != 3 )
        printf( "hey!!!\n" );
    else
        printf( "%d %d %d\n", a, b, c );
}

Which is to say that the %1d will read one digit at a time.


The following example comes from section 7.21.6.2 of the draft C11 specification

EXAMPLE 2 The call:
    #include <stdio.h>
    /* ... */
    int i; float x; char name[50];
    fscanf(stdin, "%2d%f%*d %[0123456789]", &i, &x, name);

with input:
    56789 0123 56a72
will assign to i the value 56 and to x the value 789.0, will skip 0123,
and will assign to name the sequence 56\0. The next character read from 
the input stream will be a.

That's the way it's always been, so if your compiler doesn't do that, you need to get a new compiler.




回答2:


The short answer to your question is no. The %d tag will grab the largest integer that it can, not just a single digit unless there is some sort of delimiting space in the string.

The general way to solve this would be to read the input as a string, then tokenize the input using strtok or the like.

However, since in C strings are just character arrays, you can also just iterate through a loop and call on string[0], string[1], and so on, and turn each of those into an integer separately as long as you know the length of the input beforehand, which given your explanation it sounds like you do.




回答3:


Well, I just tested the following program:

#include <stdio.h>

int main (void) {
    int n, x, y, z;

    n = sscanf ("1234567890", "%1d%1d%1d", &x, &y, &z);

    printf ("Found %d items: %d, %d and %d\n", n, x, y, z);

    return 0;
}

I compiled it under Slackware Linux, with the stock GCC and glibc. It outputs:

Found 3 items: 1, 2 and 3

So, it seems it should work the way you would like it to, but I'm not sure if this is actually standard behaviour or rather a GCC extension.

An alternative would be reading one character at a time with %1c and then converting that to the corresponding integer with atoi() or simply subtracting '0' from it, if you must/want to absolutely use scanf() that way. Otherwise what I would do is reading the whole string with %s and then iterating on the single characters, which is very easy in C, as a string is simply an array of characters.




回答4:


Your code should work in gcc comliler. But,as it's not working, you should get the 11 digit number into a character array i.e. string and then iterate through the array while converting each character to its corresponding integer value. You can get the value by just calculating array[i]-'0' i.e d = array[0]-'0' and i1 = array[1]-'0' etc. in your case.



来源:https://stackoverflow.com/questions/28420931/universal-product-code-challenge

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!