4-битный BCD на 7-сегментный - PullRequest
3 голосов
/ 05 апреля 2020

Я делаю 4-битный BCD-декодер для 7-сегментного отображения на C.

После отображения вывода я спрашиваю, хочет ли пользователь вводить снова. Я могу отобразить желаемый результат и выйти из программы, когда не хочу вводить снова.

Проблема в том, что когда я хочу ввести снова, он не прекращает запрашивать мой ввод и печатает предыдущий ввод.

Это вывод:

This program displays the decimal equivalent of a
4-bit binary-coded decimal input on a 7-segment LED Display.

Please enter a 4-bit binary-coded decimal: 1000
You've entered 1000.

The decimal equivalent is 8.

              _
             |_|
LED Display: |_|


Would you like to input another 4-bit BCD?
Enter [1] if yes or [0] if no. 1
Please enter a 4-bit binary-coded decimal: You've entered 1000.

The decimal equivalent is 8.

              _
             |_|
LED Display: |_|


Would you like to input another 4-bit BCD?
Enter [1] if yes or [0] if no.

Это мой код:

int main() {
    int i, dec, retry = 1; //declare integers i ,dec, and retry
    int bit[4]; //declare integer array with 4 elements
    unsigned char input[5]; //declare string with 5 elements

    printf("This program displays the decimal equivalent of a\n 4-bit binary-coded decimal input on a 7-segment LED Display.\n\n");

    do {         
        printf("Please enter a 4-bit binary-coded decimal: "); //instructs user to enter 4-bit bcd
        scanf("%[^\n]%*c", input); //read string
        printf("You've entered %s.\n\n", input); //shows the 4-bit bcd input 

        for (i=0; i<5; i++) {
            bit[i] = input[i] - '0';
        }

        dec = bit[0]*8 + bit[1]*4 +bit[2]*2 + bit[3];
        printf("The decimal equivalent is %d.\n\n", dec); //shows decimal equivalent

        switch (dec) { //displays 7-segment display depending on the value of dec
            case 0:
                printf("              _ \n             | |\nLED Display: |_|\n");     
                break;
           ...
        }
        printf("\n\nWould you like to input another 4-bit BCD?\nEnter [1] if yes or [0] if no. ");
        scanf("%d", &retry); 
    }
    while (retry == 1);   
}

Я также сталкиваюсь с той же проблемой при использовании fgets(input, sizeof(input), stdin); вместо scanf("%[^\n]%*c", input);

Ответы [ 2 ]

2 голосов
/ 05 апреля 2020

После ввода 1\n для go на следующем 7 сегментном номере , только 1 захватывается scanf() и \n остается на следующем .

Но формат %[^\n] указывает scanf() НЕ соответствовать ни одному входу, начинающемуся с \n, поэтому остаток, следующий за ним, возвращает без какого-либо значения scanf'd. Проверяя его возвращаемое значение, вы обнаружите, что второй раз равен 0, поэтому переменная не обновляется, и поэтому используется предыдущее значение.

Для того, чтобы исправить это, так как вам нужно %[^\n] для обрезки ввод (вы ожидаете только цифры), просто добавьте пробел перед текущим форматом ввода:

scanf(" %[^\n]%*c", input);

таким образом любой символ пробела (все символы, для которых isspace () возвращает значение true, включая '\n', ' ' и '\t').

Обратите внимание, что добавление

fflush(stdin);

перед первым scanf() равно Неопределенное поведение для стандарта C. В некоторых средах это работает, , но этого решения следует избегать, поскольку, по меньшей мере, он делает код непереносимым !

Примечание: у вас есть такое же поведение с fgets(), потому что он читает, пока не будет найден \n, и, как это было раньше с scanf, это именно тот символ, который остался от предыдущей вставки пользовательского ввода.


Предложения по как проверить ввод

Вместо использования формата %[^\n], я предлагаю другой подход для проверки ввода:

while( 1 )
{
    printf("Please enter a 4-bit binary-coded decimal: "); //instructs user to enter 4-bit bcd
    scanf(" %4s", input); //read string

    if( validateBinaryInput( input, 4 ) == 0 )
    {
        break;
    }
    else
    {
        printf( "Wrong input!\n" );
    }
}

С scanf(" %4s", input); вы точно захватите четыре символа, и хранить их в массиве input. L oop гарантирует, что всякий раз, когда ввод недействителен, последовательность ввода повторяется. Правильность ввода можно проверить с помощью функции validateBinaryInput(). Ниже приведен пример реализации:

/* Returns 0 on success, -1 on failure */
int validateBinaryInput( unsigned char *input, size_t len )
{
    int ret = 0;

    if( !input )
    {
        ret = -1;
    }
    else
    {
        int i;
        for( i=0; i<len; i++ )
        {
            if( input[i] != '0' && input[i] != '1' )
                ret = -1;
        }
    }

    return ret;
}

Он не только проверяет, что каждый вставленный символ является ди git, но и проверяет, является ли он двоичным ди git. , Таким образом вы избегаете странного поведения, которое может возникнуть при вставке ввода, такого как 5: ваше присвоение

dec = bit[0]*8 + bit[1]*4 +bit[2]*2 + bit[3];

приведет к значению 5 и соответствующим 7-сегментам di git будет напечатано, даже если ввод не является допустимым двоичным словом.

1 голос
/ 05 апреля 2020

Эта строка прямо здесь является проблемой:

      scanf("%[^\n]%*c", input); //read string

Предыдущая %d использует только пробелы перед спецификатором формата, а не после. Это означает, что scanf будет читать пустую строку.

Чтобы исправить это, добавьте пробел перед тем, чтобы пропустить :

      scanf(" %[^\n]%*c", input); //read string
...