Ошибки в коде (конечный автомат)
Я немного схожу с ума, пытаясь исправить этот код. Я был на этом почти два часа, и я не могу найти, что не так.
Это простая программа, которая должна принимать некоторый текст в качестве входных данных и возвращать один и тот же текст со всеми числами, переключенными с десятичного на шестнадцатеричное основание.
#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;
}
Программа, однако, не работает правильно, по какой-то причине я продолжаю неправильно конвертировать в hex. Почему это происходит? Большое спасибо.
3 ответа
Когда я печатаю 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;
Если вы собираетесь копировать-вставить функцию, вы должны по крайней мере убедиться, что она работает, прежде чем полагаться на нее в своем коде.
Следующий код фактически не дополняет число 2, поскольку шестнадцатеричные значения не имеют знака, только величина.
Тем не менее, это работает как ожидалось (для каждого тестового примера, который я использовал)
Он демонстрирует предпочтительную логику для обработки конечного автомата, включая то, как легко обрабатывать переходы состояний.
следующий код не меняет цифры в номере, вы можете легко добавить эту функцию, которая заменит вызов 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
Ваша функция разворота создает число, отличное от того, что было введено. Измените "+=" на "=", чтобы начать. поместите операторы print для readNum и writeNum после функции, и вы увидите проблемы
Функция также портится, если введенное число кратно 10. Вы можете вычислить эту часть.