程序不会停止到scanf

c scanf

539 观看

1回复

23 作者的声誉

这是我的名为test1的输入文件:

00 READ 9
01 READ 10
02 LOAD 9
03 SUB 10
04 BRNG 7
05 WRIT 9
06 HALT 99
07 WRIT 10
08 HALT 99
09 SET 0
10 SET 0

这些命令应该从用户读取两个值并输出两个中较大的一个。

我使用以下命令在unix上编译:

gcc -Wall -ansi -pedantic -std = c99 computer.c

并且该程序可以正常编译。

我使用以下命令运行它:

./a.out

这是我的头文件computer.h:

int dataDump (int memory [], int* accumulator, int* instructionCounter, int* instructionRegister, int* operationCode, int* operand);
int compile (int memory [], int* accumulator, int* instructionCounter, int* instructionRegister, int* operationCode, int* operand);
int execute (int memory [], int* accumulator, int* instructionCounter, int* instructionRegister, int* operationCode, int* operand);

这是我的名为computer.c的源代码文件:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "computer.h"

int main ()

{
    int memory [100] = {0};
    int accumulator = 0;
    int instructionCounter = 0;
    int instructionRegister = 0;
    int operationCode = 0;
    int operand = 0;

    compile(memory, &accumulator, &instructionCounter, &instructionRegister, &operationCode, &operand);
    execute(memory, &accumulator, &instructionCounter, &instructionRegister, &operationCode, &operand);

    return 0;
}

//This function works correctly
int compile (int memory [], int* accumulator, int* instructionCounter, int* instructionRegister, int* operationCode, int* operand)
{
    char word[4];

    while ((*operationCode = scanf("%d %s %d", accumulator, word, operand)) > 0)
    {
        if (strncmp("SET", word, 4) != 0 && *operand > 99)
        {
            printf("ERROR Word overflow");
            exit(1);
        }

        if (strncmp("SET", word, 4) == 0 && *operand > 9999)
        {
            printf("ERROR Word overflow");
            exit(1);
        }

        if (strncmp("READ", word, 4) == 0)
            memory[*accumulator] = 1000 + *operand;
        else if (strncmp("WRIT", word, 4) == 0)
            memory[*accumulator] = 1100 + *operand;
        else if (strncmp("PRNT", word, 4) == 0)
            memory[*accumulator] = 1200 + *operand;
        else if (strncmp("LOAD", word, 4) == 0)
            memory[*accumulator] = 2000 + *operand;
        else if (strncmp("STOR", word, 4) == 0)
            memory[*accumulator] = 2100 + *operand;
        else if (strncmp("SET", word, 3) == 0)
            memory[*accumulator] = *operand;
        else if (strncmp("ADD", word, 3) == 0)
            memory[*accumulator] = 3000 + *operand;
        else if (strncmp("SUB", word, 3) == 0)
            memory[*accumulator] = 3100 + *operand;
        else if (strncmp("DIV", word, 3) == 0)
            memory[*accumulator] = 3200 + *operand;
        else if (strncmp("MULT", word, 4) == 0)
            memory[*accumulator] = 3300 + *operand;
        else if (strncmp("MOD", word, 3) == 0)
            memory[*accumulator] = 3400 + *operand;
        else if (strncmp("BRAN", word, 4) == 0)
            memory[*accumulator] = 4000 + *operand;
        else if (strncmp("BRNG", word, 4) == 0)
            memory[*accumulator] = 4100 + *operand;
        else if (strncmp("BRZR", word, 4) == 0)
            memory[*accumulator] = 4200 + *operand;
        else if (strncmp("HALT", word, 4) == 0)
        {
            memory[*accumulator] = 9900 + *operand;
            *instructionCounter = 1;
        }
        // add HALT error and word not found error
    }

    if (*operationCode == 0)
    {
        printf("ERROR Undefined use");
        exit(1);
    }

    if (*instructionCounter == 0)
    {
        printf("ERROR No HALT");
        exit(1);
    }

    return 0;
}

// the bug is in this function
int execute (int memory [], int* accumulator, int* instructionCounter, int* instructionRegister, int* operationCode, int* operand)
{
    *accumulator = 0;
    *instructionCounter = 0;
    *instructionRegister = 0;
    *operationCode = 0;
    *operand = 0;

    for (*instructionCounter = 0; *instructionCounter < 100; *instructionCounter += 1)
    {
        *instructionRegister = memory[*instructionCounter];
        *operationCode = *instructionRegister / 100;
        *operand = *instructionRegister % 100;

        switch (*operationCode)
        {
            case 10:
                //printf("got here");
                scanf("%d", &memory[*operand]); // won't stop to scan in input here
                // I even tried putting a space before the %d and it still won't work
                // I also tried fflush(stdin) before scanf and it still wouldn't stop
                break;

            case 11:
                printf("%d", memory[*operand]);
                break;

            case 12:
                while (memory[*operand] != 0)
                {
                    if (memory[*operand] / 100 == 10 || (memory[*operand] / 100 >= 65 && memory[*operand] / 100 <= 90))
                    {
                        printf("%c",  memory[*operand] / 100);
                    }
                    else
                    {
                        printf("ERROR Unknown Character");
                        exit(1);
                    }

                    if (memory[*operand] % 100 == 10 || (memory[*operand] % 100 >= 65 && memory[*operand] % 100 <= 90))
                    {
                        printf("%c",  memory[*operand] % 100);
                    }
                    else if (memory[*operand] % 100 == 0)
                    {
                        break;
                    }
                    else
                    {
                        printf("ERROR Unknown Character");
                        exit(1);
                    }

                    *operand += 1;
                }

                break;

            case 20:
                *accumulator = memory[*operand];
                break;

            case 21:
                memory[*operand] = *accumulator;
                break;

            case 30:
                *accumulator += memory[*operand];
                break;

            case 31:
                *accumulator -= memory[*operand];
                break;

            case 32:
                if (memory[*operand] != 0)
                {
                    *accumulator /= memory[*operand];
                }
                else
                {
                    printf("ERROR Divide 0");
                }

                break;

            case 33:
                *accumulator *= memory[*operand];
                break;

            case 34:
                if (memory[*operand] != 0)
                {
                    *accumulator %= memory[*operand];
                }
                else
                {
                    printf("ERROR Divide 0");
                }

                break;

            case 40:
                *instructionCounter = memory[*operand] - 1;
                break;

            case 41:
                if (*accumulator < 0)
                {
                    *instructionCounter = memory[*operand] - 1;
                }

                break;

            case 42:
                if (*accumulator == 0)
                {
                    *instructionCounter = memory[*operand] - 1;
                }

                break;

            case 99:
                dataDump(memory, accumulator, instructionCounter, instructionRegister, operationCode, operand);
                return 0;
                break;

            default:
                printf("ERROR Unknown command");
                exit(1);
                break;
        }
    }

    return 0;
}

//This function works correctly
int dataDump (int memory [], int* accumulator, int* instructionCounter, int* instructionRegister, int* operationCode, int* operand)
{
    printf("\nREGISTERS:\n");
    printf("%-25s%+05d\n", "accumulator", *accumulator);
    printf("%-28s%02d\n","instructionCounter", *instructionCounter);
    printf("%-25s%+05d\n","instructionRegister", *instructionRegister);
    printf("%-28s%02d\n","operationCode", *operationCode);
    printf("%-28s%02d\n", "operand", *operand);
    printf("MEMORY:\n   ");

    for(*accumulator = 0; *accumulator <= 9; *accumulator += 1)
    {
        printf("%5d ", *accumulator);
    }

    for(*accumulator = 0; *accumulator < 100; *accumulator += 1)
    {
        if(*accumulator % 10 == 0)
            printf("\n%2d ", *accumulator);

        printf("%+05d ", memory[*accumulator]);
    }

    printf("\n");

    return 0;
}

这是输出:

0
REGISTERS:
accumulator              +0000
instructionCounter          06
instructionRegister      +9999
operationCode               99 
operand                     99
MEMORY:
       0     1     2     3     4     5     6     7     8     9
 0 +1009 +1010 +2009 +3110 +4107 +1109 +9999 +1110 +9999 +0000
10 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
20 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
30 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
40 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
50 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
60 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
70 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
80 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
90 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000
作者: Michael Kiroff 的来源 发布者: 2017 年 3 月 11 日

回应 1


0

348 作者的声誉

如果我理解正确,compile()应该从文件中读取“程序”,并execute()运行所述程序。您面临的问题是execute()应该从用户那里获取输入,但是scanf却不要求输入。

如果是这种情况,那么您观察到的行为是可以预期的。您正在使用输入重定向(./a.out < test1)从文件中获取数据,因此,当您希望scanf接收用户输入时,它会再次尝试从文件中读取并要求用户不输入任何内容。检查如果是这样的情况,你可以printf右键后scanf,看看被读取。

为了解决这个问题,而不是使用输入redirectiong读取文件,你应该使用文件访问(fopen()fclose()fscanf()fprintf(),等...)。将文件名作为命令行参数(./a.out test1)传递,然后使用进行检索argv[]。从文件中读取您需要的内容。用户要求输入数据后,请使用scanf(),现在可以从控制台正确读取数据。

作者: AmiguelS 发布者: 2017 年 3 月 12 日
32x32