简体   繁体   English

C程序未按预期运行,在输入后挂起

[英]C Program not running as intended, hangs after input

The program I am writing to take a number and display that number as a calculator would display it (shown below) is compiling with no issues, but when I try to run it, I am able to input my number, but nothing happens. 我写的程序拿一个数字并显示该数字作为计算器将显示它(如下所示)正在编译没有问题,但当我尝试运行它时,我能够输入我的数字,但没有任何反应。 It seems like it is "hanging", since no further output is shown as I would have expected. 它似乎是“悬挂”,因为没有显示出我预期的进一步输出。 Might anyone know what the problem is? 可能有人知道问题是什么?

#include <stdio.h>
#define MAX_DIGITS 20

char segments[10][7] =              /* seven segment array */
    {{'1','1','1','1','1','1','0'}, /* zero */
     {'0','1','1','0','0','0','0'}, /* one */
     {'1','1','0','1','1','0','1'}, /* two */
     {'1','1','1','1','0','0','1'}, /* three */
     {'0','1','1','0','0','1','1'}, /* four */
     {'1','0','1','1','0','1','1'}, /* five */
     {'1','0','1','1','1','1','1'}, /* six */
     {'1','1','1','0','0','0','0'}, /* seven */
     {'1','1','1','1','1','1','1'}, /* eight */
     {'1','1','1','0','0','1','1'}};/* nine */
char digits[3][MAX_DIGITS * 4];     /* digits array */
int i, j;                           /* count variables */
int adjust;                         /* output formatting */

int main(void) {
    clear_digits_array();

    int digit[20];
    for (i = 0; i < 20; i++) {
        digit[i] = 0;
    }

    int count = 20;
    int position = 0;

    printf("Enter a number: ");

    int number = scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
            &digit[0],
            &digit[1],
            &digit[2],
            &digit[3],
            &digit[4],
            &digit[5],
            &digit[6],
            &digit[7],
            &digit[8],
            &digit[9],
            &digit[10],
            &digit[11],
            &digit[12],
            &digit[13],
            &digit[14],
            &digit[15],
            &digit[16],
            &digit[17],
            &digit[18],
            &digit[19]);                        //NOTHING HAPPENS AFTER HERE

    printf("Got input, number is %d", number); 

    while (count > 0) {
        printf("Reading digits, count is %d", count);
        process_digit(digit[20 - count], position);
        position++;
        count--;
    }

    print_digits_array();
    printf("\n");
    return 0;
}

void clear_digits_array(void) {
    /* fill all positions in digits array with blank spaces */
    for (i = 0; i < 3; i++) {
        for (j = 0; j < (MAX_DIGITS * 4); j++) {
            digits[i][j] = ' ';
        }
    }
}

void process_digit(int digit, int position) {
    /* check each segment to see if segment should be filled in for given digit */
    for (i = 0; i < 7; i++) {
        printf("Processing digit %d at position %d, i is %d", digit, position, i);
        if (segments[digit][i] == 1) {
            switch (i) {
                case 0: digits[0][(position * 4) + 1] = '_';
                        break;
                case 1: digits[1][(position * 4) + 2] = '|';
                        break;
                case 2: digits[2][(position * 4) + 2] = '|';
                        break;
                case 3: digits[2][(position * 4) + 1] = '_';
                        break;
                case 4: digits[2][(position * 4) + 0] = '|';
                        break;
                case 5: digits[1][(position * 4) + 0] = '|';
                        break;
                case 6: digits[1][(position * 4) + 1] = '_';
                        break;
            }
        }
    }
}

void print_digits_array(void) {
    /* print each character in digits array */
    for (i = 0; i < 3; i++) {
        for (j = 0; j < (MAX_DIGITS * 4); j++) {
            printf("%c", digits[i][j]);
        }
        printf("/n");
    }
}

Your code includes: 您的代码包括:

printf("Enter a number: ");

int number = scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
        &digit[0],
        &digit[1],
        &digit[2],
        &digit[3],
        &digit[4],
        &digit[5],
        &digit[6],
        &digit[7],
        &digit[8],
        &digit[9],
        &digit[10],
        &digit[11],
        &digit[12],
        &digit[13],
        &digit[14],
        &digit[15],
        &digit[16],
        &digit[17],
        &digit[18],
        &digit[19]);                        //NOTHING HAPPENS AFTER HERE

Have you entered twenty separate digits? 你输入了二十个数字吗? If not, scanf() is waiting for you to type some more numbers. 如果没有, scanf()等待您输入更多数字。

Note that the return value from scanf() is the number of successfully converted numbers (0..20 in the example), not the value you entered. 请注意, scanf()的返回值是成功转换的数字的数量(示例中为0..20),而不是您输入的值。


Is that the issue? 这是问题吗? I tried to make it such that the maximum amount of numbers the user could enter was 20, and if any more were entered they would be ignored, or if fewer were entered, it would only consider those (say, 5 were entered, then only the 5 would be used). 我试图使用户输入的最大数量为20,如果输入的数量更多,则会被忽略,或者如果输入的数量更少,则只考虑那些(例如,输入的数字为5,然后仅输入将使用5)。 Is there an easier way to do this sort of thing then? 有没有更简单的方法来做这种事情呢?

Yes, I think that's the issue. 是的,我认为这是问题所在。

There are probably several easier ways to do it. 可能有几种更简单的方法。 I'd be tempted to use: 我很想使用:

char buffer[22];  // 20 digits, newline, null
if (fgets(buffer, sizeof(buffer), stdin) != EOF)
{
    size_t len = strlen(buffer);
    if (len >= sizeof(buffer) - 1)
    {
        fprintf(stderr, "You entered too long a string (maximum 20 digits)\n");
        exit(EXIT_FAILURE);
    }
    if (len > 0)
        buffer[--len] = '\0';  // Zap newline — carefully
    for (int i = 0; i < len; i++)
    {
        if (!isdigit(buffer[i]))
        {
            fprintf(stderr, "Non-digit %c found\n", buffer[i]);
            exit(EXIT_FAILURE);
        }
    }
    ...and from here, process the digits in buffer, one at a time...
    ...Use buffer[i] - '0' to get a number 0..9 from the character in buffer...
}

Another option is to use a long long number, but that only gives you up to 18 digits (signed) or 19 digits (unsigned), with some values of 19 or 20 also within range. 另一种选择是使用long long号码,但这只能给你18个数字(有符号)或19个数字(无符号),有些值在19或20范围内。 You'd then strip the digits out of the number using division and modulus operations. 然后,您将使用除法和模数运算从数字中删除数字。

long long value;
if (scanf("%lld", &value) == 1)
{
    if (value < 0)
        ...error processing...
    do
    {
        int digit = value % 10;
        value /= 10;
        ...process digit...
    } while (value > 0);
}

This has some merits, but in practice, I'd be tempted to use fgets() to read a line of input, and either sscanf() or strtoll() to convert and validate the number. 这有一些优点,但在实践中,我很想使用fgets()来读取一行输入,并使用sscanf()strtoll()来转换和验证数字。 That isn't as simple as it looks; 这并不像看起来那么简单; the error returns from strtoll() , in particular, are many and subtle, and none of the scanf() family handle overflowing numbers gracefully. strtoll()返回的错误,特别是很多很细微,而scanf()系列都没有优雅地处理溢出的数字。 You could constrain the scanf() though with %18lld so that no more than 18 digits are read, but that would mean that if the user typed 19 or more digits, you'd get the leftovers on the next attempt to read with scanf() . 您可以使用%18lld约束scanf() ,以便读取不超过18位,但这意味着如果用户键入19位或更多位数,您将在下次尝试使用scanf()读取剩余时间scanf() So, handling scanf() is not simple either, especially if you need to convert multiple numbers in a single run of the program. 因此,处理scanf()也不简单,特别是如果您需要在程序的单次运行中转换多个数字。

With those caveats out of the way, you can usually do a 'good enough' job with a sensible person providing the input. 有了这些注意事项,你通常可以通过提供意见的明智的人来做一个“足够好”的工作。 It is the process of making a program bomb-proof (foolproof — as in, proof against fools) that is hard. 这是一个制定程序防弹的过程(万无一失 - 如同对傻瓜一样证明)很难。 I find meaningful error reporting easier when I can report the whole string that was read in (as with fgets() ); 当我可以报告读入的整个字符串时(与fgets() ),我发现有意义的错误报告更容易; with scanf() , you can't see the characters that were entered and consumed before something went wrong. 使用scanf() ,您无法在出现错误之前看到输入和消耗的字符。

int number = scanf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d",
            &digit[0],
            &digit[1],
            &digit[2],
            &digit[3],
            &digit[4],
            &digit[5],
            &digit[6],
            &digit[7],
            &digit[8],
            &digit[9],
            &digit[10],
            &digit[11],
            &digit[12],
            &digit[13],
            &digit[14],
            &digit[15],
            &digit[16],
            &digit[17],
            &digit[18],
            &digit[19]);         

I don't think this is a good idea use loop here 我不认为这是一个好主意在这里使用loop

for (i = 0; i < 20; i++) 
        scanf("%d",&digit[i]);

And if you need the number then do like this 如果你需要这个number那就这样做吧

int number = i; when loop finishes. 当循环结束。

You can also try this 你也可以试试这个

char buf[12]; 
while((c=getchar())!=EOF && i < 20)
{
 buf[j++] =c;
 if((c == '\n' || c == ' ' || c == '\t') && (sscanf(buf,"%d",&digit[i])) == 1)
   {
    i++;
    j = 0;
   }
 }

For EOF you will have to press CTRL+D In this way you can take 20 or less integers 对于EOF,您必须按CTRL+D这样您可以采用20或更少的整数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM