2017-03-11 59 views
0

這是我的輸入文件名爲test1:程序不會停下來SCANF

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 < test1的

這裏是我的頭文件名爲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 
+1

您將文件'test1'重定向到stdin,並且'compile'直到EOF。因此,當'execute'調用'scanf'時,仍然沒有任何要讀的東西。您可能想要將該程序解釋爲命令行參數,而不是stdin。 – zwol

回答

0

如果我理解正確的話,應該compile()從文件中讀取的「程序」,並​​應該說運行程序。而您面臨的問題是​​應該從用戶那裏得到輸入,而不是scanf不要求輸入。

如果是這種情況,那麼您觀察到的行爲是預期的。您正在使用輸入重定向(./a.out < test1)從文件中獲取數據,因此,如果您期望scanf需要用戶輸入,則它會再次嘗試從文件中讀取數據並要求用戶不要輸入。檢查是否是這種情況,您可以在scanf之後printf並查看所讀的內容。

爲了解決這個問題,而不是使用輸入redirectiong讀取文件,你應該使用文件訪問(fopen()fclose()fscanf()fprintf(),等...)。將文件的名稱作爲命令行參數傳遞(./a.out test1),然後使用argv[]檢索它。從文件中讀取你的內容。一旦用戶需要輸入數據,使用scanf(),現在可以從控制檯正確讀取數據。