代码错误(状态机)

Errors on code (state machine)

我要修复这段代码有点疯狂。我已经弄了将近两个小时了,我找不到问题所在。

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

#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;
}

但是,该程序无法正常运行,出于某种原因,我一直无法正确转换为十六进制。为什么会这样?非常感谢。

当我在命令行中键入 123 时,您的程序在内部存储:1*1 + 2*10 + 3*100 = 321 这是相反的,很好。但是,你的函数要反转 321 returns 146 而不是 123。那里肯定有问题。

我建议初学者看看这个:

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

问题是这一行:

revNum += revNum * 10 + n%10;

应该是:

revNum = revNum * 10 + n%10;

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

您的反转函数创建的数字与输入的数字不同。将“+=”更改为“=”以开始。在函数之后放置 readNum 和 writeNum 的打印语句,你会看到问题

如果输入的数字是 10 的倍数,函数也会出错。你可以弄清楚这部分。

以下代码实际上并不是 2 的补码,因为十六进制值没有符号,只有大小。

但是,这按预期工作(对于我使用的每个测试用例)

它演示了处理状态机的首选逻辑,包括如何轻松处理状态转换。

以下代码不会反转数字中的数字,您应该能够轻松添加该功能,这将取代 inNumber() 函数

中对 printf() 的调用
#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