2013-06-03 5 views
1

Вход должен иметь формат целочисленного слова integer с пробелами между ними. Я написал код ниже, и насколько я могу сказать, он работает. Теперь я работаю над частью проверки ошибок кода.Возвращаемые значения scanf и проверка входов

Если ввод не соответствует формату, как бы я его проверил?

Три типа ошибок, которые необходимо проверить, будут иметь следующие форматы ввода: «WORD 99», «10WORD 33» и «10 WORD».

Чтобы подробнее рассказать. Вход имеет вид 10 READ 10. Первое целое число 10 - это адрес памяти, в который будет храниться остальная часть ввода. Слово или READ в этом случае является инструкцией. Функция convertOpCode соответствует буквам слова, чтобы найти совпадение с известными инструкциями и сохраняет код команды в регистре кода операции, который является * operationCode. Второе целое число - это адрес, который использует операция. Чтение сохранит вход пользователя во входное местоположение второго целого.

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

Кроме того, меня ограничивают только показанные переменные. У меня есть «память» массива int, чтобы сохранить результаты компиляции и показанные 5 переменных int. Я не могу создавать другие массивы или буферы.

int compile(int memory[], int *accumulator, int *instructionCounter, 
    int *instructionRegister, int *operationCode, int *operand){ 

while(scanf("%d", accumulator) == 1){ 

    *instructionRegister = convertOpCode(instructionCounter, instructionRegister, operationCode, operand); 
    if(*instructionRegister == 0){ 
     ERRORUC(accumulator); 
    scanf("%d", operand); 
    if(*operationCode != 22){ 
     if(*operand > 99){ 
      ERROROPERAND(accumulator); 
     memory[ *accumulator ] = ((*operationCode) * 100) + (*operand); 
    } 
    else{ 
     if(*operand > 9999){ 
      ERRORSET(accumulator); 
     } 
     memory[ *accumulator ] = *operand; 
    } 
} 
checkHalt(memory, instructionCounter, accumulator); 
print(memory); 
return 0; 

}

В соответствии с просьбой вот как функция convertOpCode выглядит.

int convertOpCode(int *reg1, int* reg2, int* opCode, int* reg3){ 

    getchar(); 
    *reg1 = (int)getchar(); 
    *reg2 = (int)getchar(); 
    *reg3 = (int)getchar(); 
    *opCode = (int)getchar(); 

    switch(*reg1){ 
     case (int)'R': 
      if(*reg2 == (int)'E' && *reg3 == (int)'A' && *opCode == (int)'D'){ 
       *reg1 = (int)getchar(); 
       if(*reg1 == (int)' '){ 
        *opCode = READ; 
        return 1; 
       }else{ 
        return 0; 
       } 
      }else{ 
       return 0; 
      } 
     case (int)'W'..... 

}

+0

В чем смысл 'WORD 99',' 10WORD 33' и '10 WORD', каковы ожидаемые входы, и что делает функция' convertOpCode() 'convert? –

+0

Из-за ограничений, установленных на нас, я могу использовать только 5 целых чисел по всей программе. @bubberboots, надеюсь, я объяснил это лучше в новом редактировании вопроса. – user1362058

+1

Почему бы не сразу получить все значения? Использовать fgets, например chux, предлагает «sscanf (буфер,«% s% s% s », один, два, три);». Затем вы можете использовать такие вещи, как «isalpha()» и возвращаемое значение sscanf, чтобы решить, как обрабатывать отсканированные элементы. Также мне кажется ужасно небезопасным рассматривать ввод программы как индекс в массив - особенно без проверки границ. – n0741337

ответ

0

Я думаю, что я бы не стал злоупотреблять другими Интс для чтения символов опкодами. Я не совсем точно знаю требования задачи, но в прошлом я преподавал C, и я бы не сделал такого требования, если нет другого пути (ваш босс может отличаться :-)).

Я думаю, что вы можете разбирать персонажи, когда вы их читаете, создавая структуру корпуса, которая является своего рода деревом разрешенных слов. Допустим, (например, и simplicty) у вас есть инструкции ASK MUL SUB

int getopcode() 
{ 
    if (getchar()==' ') { // ok, starting with space 

     switch (getchar()) {  

      case 'A': // probably A(DD) but make sure ... 
       if (getchar()=='D' && getchar()=='D') { 
        return 1; // opcode for ADD 
       } 
       break; 


      case 'M': // probably M(UL) but make sure ... 
       if (getchar()=='U' && getchar()=='L') { 
        return 2; // opcode for MUL 
       } 
       break; 

      .... 
     } 
    } 

    return 0; // error if we arrive here. 
} 

Если у вас есть операции, которые начинаются с той же буквы (ADD и ASK) вам понадобится 2-й переключатель сложены внутри «A 'перейти на вторую букву.

Для основной программы, я просто resketched, что немного для дополнительной проверки ошибок (не уверен, что некоторые из ваших макросов, как ERRORUC, но я уверен, что вы получите картину):

while(scanf("%d", accumulator) == 1){ 

    *instructionRegister = getopcode(); 
    if (*instructionRegister!=0) { 

     if (scanf(" %d", operand)==1) { // ok, one more decimal operand 

      switch (*operationCode) { // operand error checking per opcode 

       case 22: 
         if(*operand> 99) 
          ERROROPERAND(accumulator); 
         break; 

       default: 
         if(*operand > 9999) 
          ERRORSET(accumulator); 
         break; 
      } 
     } 
     else { 
      // error reading 2nd operand 
      ERRORUC(accumulator); 
     } 

    } 
    else { 
     // error in opcode 
     ERRORUC(accumulator); 
    } 


    if (no error set in accumulator, i.e. no ERRORxx macro called) { 
     // accumulator, instructionRegister and operand are ok here 
     // write to memory 
    } 
    else 
     break; // break the loop, end compiling 
} 

print(memory); 
return 0; 

что-то необходимо выполнить разбиение цикла на основе ошибки или не сделать его циклом изначально.

+0

спасибо, не понял, что будет работать – user1362058

+0

Добавлен бит кода для основной программы. – Nicholaz

Смежные вопросы