2015-11-23 132 views
1

我想要修复这段代码有点疯狂。我已经呆了将近两个小时,我找不到什么不对。代码错误(状态机)

这是一个简单的程序,它应该将一些文本作为输入并返回相同的文本,并将所有数字从十进制转换为十六进制基数。

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 

int revNumber(int); 

typedef enum { STATE_WORD, STATE_BLANK, STATE_NUMBER } state_t; 

int main() 
{ 
    int c; 
    int readNum = 0; 
    int writeNum = 0; 
    int digit = 1; 
    int sign = 1; 

    state_t state = STATE_BLANK; 

    while((c = getchar()) != EOF) 
    { 
     switch(state) 
     { 
      case STATE_WORD: 
       if(isspace(c)) 
        state = STATE_BLANK; 
       putchar(c); 
       break; 

      case STATE_BLANK: 
       if(c == '-') 
       { 
        sign = -1; 
        state = STATE_NUMBER; 
       } 
       else if(isdigit(c)) 
       { 
        readNum += (c - '0') * digit; 
        digit *= 10; 
        state = STATE_NUMBER; 
       } 
       else if(isspace(c)) 
        putchar(c); 

       else 
       { 
        state = STATE_WORD; 
        putchar(c); 
       } 
       break; 

      case STATE_NUMBER: 
       if(isdigit(c)) 
       { 
        readNum += (c - '0') * digit; 
        digit *= 10; 
       } 
       else 
       { 
        writeNum = revNumber(readNum); 
        readNum = 0; 

        if(sign == -1) 
         putchar('-'); 

        if(digit > 1) 
        { 
         if(isspace(c)) 
         { 
          printf("%x", writeNum); 
          state = STATE_BLANK; 
         } 
         else 
         { 
          printf("%d", writeNum); 
          state = STATE_WORD; 
         } 
        } 
        digit = 1; 
        sign = 1; 
        putchar(c); 
       } 
       break; 
     } 
    } 
} 


int revNumber(int n) 
{ 
    int revNum = 0; 
    while(n != 0) 
    { 
     revNum += revNum * 10 + n%10; 
     n /= 10; 
    } 
    return revNum; 
} 

但是,该程序无法正常工作,由于某些原因我不断收到转换为十六进制错误。为什么会发生?非常感谢。

+0

任何错误代码,你是后得到编译你的代码 – mumair

+0

你是什么意思?我没有收到编译错误。 – YoTengoUnLCD

+0

尝试使用'-Wall -Wtratra'进行编译。然而,这不是你问题的原因。 – tonysdg

回答

1

当我在命令行键入123时,你的程序在内部存储:1*1 + 2*10 + 3*100 = 321这是相反的,罚款。但是,然后,您的功能321返回146而不是123。那里肯定有错。

我建议看这对于初学者:

http://www.programmingsimplified.com/c/source-code/c-program-reverse-number

的问题是,这条线:

revNum += revNum * 10 + n%10;

应该是:

revNum = revNum * 10 + n%10;

如果你要复制一个函数,你至少应该在你的代码中依赖它之前验证它是否有效。

+0

问题是我没有复制粘贴该功能,我做了它,并一直在看它认为它工作正常。谢谢您的帮助。 – YoTengoUnLCD

+0

我只是假设你复制粘贴,因为它非常类似于[这里](http://www.programmingsimplified.com/c/source-code/c-program-reverse-number),甚至下到奇怪的间距'n/= 10;'。 – RPGillespie

1

你是反转功能创建一个不同于输入的数字。将“+ =”更改为“=”开始。在函数后面放置readNum和writeNum的打印语句,您将看到问题

如果输入的数字是10的倍数,该函数也会混淆。您可以将该部分计算出来。

+0

Readnum向后存储,这就是为什么revNum存在。我不试图将其转换为十六进制。 – YoTengoUnLCD

+0

我的不好。我不明白revNum()的用途。我编辑了我的答案 – petEEy

+0

谢谢!我会尽力修复那部分。 – YoTengoUnLCD

2

下面的代码实际上并不是2的恭维数,因为十六进制值没有符号,只有数量级。

然而,这种按预期工作(用于I中使用的每个测试用例)

它表明用于处理的状态机,包括如何容易地处理的状态转换的优选的逻辑。

下面的代码不会扭转数数字,你应该能够很容易地添加功能,该功能将取代调用printf()inNumber()功能

#include <stdio.h> 
#include <stdlib.h> 
#include <ctype.h> 

typedef enum { STATE_WORD, STATE_BLANK, STATE_NUMBER } state_t; 


state_t inWord (char ch); 
state_t inBlank (char ch); 
state_t inNumber(char ch); 

int number = 0; 
char sign = ' '; 

state_t state = STATE_BLANK; 


int main(void) 
{ 
    int c; 


    printf("program will echo sentence with numeric sub strings output in hex format\n"); 
    printf("Enter a sentence:"); 

    while((c = getchar()) && (c != EOF)) 
    { 
     switch(state) 
     { 
      case STATE_WORD: 
       state = inWord(c); 
       break; 

      case STATE_BLANK: 
       state = inBlank(c); 
       break; 

      case STATE_NUMBER: 
       state = inNumber(c); 
       break; 

      default: 
       printf("state machine contains invalid state\n"); 
       break; 
     } // end switch 

     if('\n' == c) 
     { 
      break; 
     } 
    } // end while 

    putchar('\n'); 
    return 0; 
} // end function: main 


state_t inWord(char ch) 
{ 
    state_t newState = STATE_WORD; 

    if(isdigit(ch)) 
    { 
     newState = inNumber(ch); 
    } 

    else 
    { 
     putchar(ch); 
    } 

    return newState; 
} // end function: inWord 


state_t inBlank(char ch) 
{ 
    state_t newState = STATE_BLANK; 

    if(isdigit(ch)) 
    { 
     newState = inNumber(ch); 
    } 

    else if(isalpha(ch)) 
    { 
     newState = inWord(ch); 
    } 

    else 
    { 
     putchar(ch); 
    } 

    return newState; 
} // end function: inBlank 


state_t inNumber(char ch) 
{ 
    state_t newState = STATE_NUMBER; 

    if(!isdigit(ch)) 
    { 
     printf("%X ", number); 
     newState = inBlank(ch); 
    } 

    else 
    { 
     number *=10; 
     number += ch-'0'; 
    } 

    return newState; 
} // end function: inNumber