2017-03-11 7 views
0

을 scanf을 멈추지 않을 것입니다 이것은 내 입력 파일 이름 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 

.

명령을 사용하여 유닉스에서 컴파일 I :

의 gcc -Wall -ansi -pedantic -std = C99 computer.c

프로그램은 잘 컴파일합니다.

다음
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.h 이름이 여기에 TEST1

< ./a.out :

나는 명령을 사용하여 실행 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()은 파일에서 'program'을 읽고, execute()은 상기 프로그램을 실행해야합니다. 그리고 당신이 직면 한 문제는 execute()이 사용자로부터 입력을 받아야한다는 것입니다. 대신 scanf은 입력을 요구하지 않습니다.

이 경우 사용자가 관찰하는 동작이 필요합니다. 입력 리디렉션 (./a.out < test1)을 사용하여 파일에서 데이터를 가져 오므로 scanf이 사용자 입력을 받겠다 고 예상 할 때 파일 형식을 다시 읽으려고 시도하고 사용자에게 입력을 요청합니다. 이 상황이 맞는지 확인하려면 printfscanf 바로 뒤에 올리고 읽을 내용을 확인하십시오.

대신, 당신은 (... 등 fopen(), fclose(), fscanf(), fprintf()) 파일 액세스를 사용해야 파일을 읽을 수 redirectiong 입력을 사용하는,이 문제를 해결합니다. 파일 이름을 명령 줄 인수 ( ./a.out test1)로 전달한 다음 argv[]으로 검색하십시오. 당신이 무엇을 물 었는지 파일에서 읽었습니다. 사용자가 데이터를 입력해야하는 경우 scanf()을 사용하면 콘솔에서 올바르게 읽을 수 있습니다.