teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2019/06/22 15:13

投稿

otn
otn

スコア86365

answer CHANGED
@@ -38,4 +38,44 @@
38
38
  学生が実習で作ったようなCコンパイラなら可能かも。
39
39
 
40
40
  普通のコンパイラの場合は、テーブルを引くなら出力するための関数を型それぞれ個別で定義しないと駄目ですね。
41
- `if`の連鎖をマクロを使って書く案が出ていますが、そういう方向がいいと思います。
41
+ `if`の連鎖をマクロを使って書く案が出ていますが、そういう方向がいいと思います。
42
+
43
+ #追記
44
+ やはり処理系依存ですが、bcc32 (Borland C)だと出来ました。
45
+ `va_list`型が、ポインタになっているタイプだと多分大丈夫。
46
+ ただし、`float`型の出力指定子は無いので、`double`にする必要があります。この特別扱いはどうしようも無いですね。
47
+ ```C
48
+ #include <stdio.h>
49
+ #include <string.h>
50
+ #include <stdlib.h>
51
+ #include <stdarg.h>
52
+
53
+ int main(void)
54
+ {
55
+ char line[1024];
56
+ char type[100];
57
+
58
+ char *types[] = {"int","float","double","char"};
59
+ char *ifmts[] = {"%d", "%f","%lf"," %c"};
60
+ char *ofmts[] = {"int=%d\n", "float=%f\n","double=%f\n","char='%c'\n"};
61
+ union {
62
+ int xi;
63
+ float xf;
64
+ double xd;
65
+ char xc;
66
+ } work;
67
+
68
+ int i;
69
+
70
+ while(fgets(line,sizeof line,stdin)){
71
+ if(sscanf(line, "%s", type)!=1) exit(1);
72
+ for(i=0; i<sizeof types/sizeof types[0]; i++){
73
+ if(!strcmp(type,types[i])) break;
74
+ }
75
+ if(i==sizeof types/sizeof types[0]) exit(2);
76
+ if(sscanf(line+strlen(type), ifmts[i], (void*)&work)!=1) exit(3);
77
+ if(i==1) work.xd = work.xf;
78
+ vprintf(ofmts[i],&work);
79
+ }
80
+ }
81
+ ```