|
Win98, LSI-C
通信で受信した電文の解析用として、"-12.345"のような文字列を-12345という値に変換する関数を作成しています。
下記のようになんとか動くものはできました。
しかし、状態変数(status)を使っていたりcontinueを使っていたりで泥臭いソースになってしまった気がしています。
もっとスマートに組めないものでしょうか。
[関数の説明]
asc: 文字列
len: 変換最大長
point: 小数点以下第何位まで変換するか
endptr: 変換を終了した文字
status: 状態変数(0:符号,1:整数部,2:小数部)
[ソース]
#include <stdio.h>
#include <ctype.h>
typedef int bool;
#define TRUE 1
#define FALSE 0
long asc2fixed(const char *asc, int len, int point, char **endptr)
{
long val;
int status;
int sign;
val = 0;
status = 0;
sign = 1;
for ( ; len > 0 && point > 0; asc++, len-- ) {
if ( status <= 0 ) {
if ( *asc == '+' ) {
status = 1;
continue;
}
else if ( *asc == '-' ) {
sign = -1;
status = 1;
continue;
}
}
if ( status <= 1 && *asc == '.' ) {
status = 2;
continue;
}
if ( !isdigit(*asc) )
break;
val = val * 10 + (*asc - '0');
if ( status == 2 ) {
point--;
}
}
while ( point-- > 0 )
val *= 10;
val *= sign;
if ( endptr != NULL )
*endptr = (char *)asc;
return val;
}
int main(void)
{
const char *tbl[] = {
"0Z",
"1Z",
"12Z",
"123Z",
"1234Z",
"12345Z",
"123456Z",
".0Z",
".1Z",
".12Z",
".123Z",
"0.Z",
"1.Z",
"1.2Z",
"1.23Z",
"1.234Z",
"+00.Z",
"-10.Z",
"+12.Z",
"-12.3Z",
"+12.34Z",
"-12.345Z",
};
const int size = sizeof(tbl)/sizeof(tbl[0]);
long val;
char *end;
int i;
for ( i = 0; i < size; i++ ) {
val = asc2fixed(tbl[i], 5, 2, &end);
printf("%-8s → %-7ld : '%c'\n", tbl[i], val, *end);
}
return 0;
}
[実行結果]
0Z → 0 : 'Z'
1Z → 100 : 'Z'
12Z → 1200 : 'Z'
123Z → 12300 : 'Z'
1234Z → 123400 : 'Z'
12345Z → 1234500 : 'Z'
123456Z → 1234500 : '6'
.0Z → 0 : 'Z'
.1Z → 10 : 'Z'
.12Z → 12 : 'Z'
.123Z → 12 : '3'
0.Z → 0 : 'Z'
1.Z → 100 : 'Z'
1.2Z → 120 : 'Z'
1.23Z → 123 : 'Z'
1.234Z → 123 : '4'
+00.Z → 0 : 'Z'
-10.Z → -1000 : 'Z'
+12.Z → 1200 : 'Z'
-12.3Z → -1230 : 'Z'
+12.34Z → 1230 : '4'
-12.345Z → -1230 : '4'
|