代码错误(状态机)
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
我要修复这段代码有点疯狂。我已经弄了将近两个小时了,我找不到问题所在。
这是一个简单的程序,应该将一些文本作为输入,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