回答編集履歴

4

追記

2020/06/10 05:07

投稿

episteme
episteme

スコア16614

test CHANGED
@@ -55,3 +55,269 @@
55
55
  あ...main() で scanf("%s", formula); やってるのもトラブルの原因。
56
56
 
57
57
  これだと空白が読みこまれず、"12 34 +" の入力に対し formulaは"12"となります。
58
+
59
+
60
+
61
+ [追記]
62
+
63
+ ```C
64
+
65
+ #define _CRT_SECURE_NO_WARNINGS
66
+
67
+ #include <stdio.h>
68
+
69
+ #include <stdlib.h>
70
+
71
+ #include <ctype.h>
72
+
73
+ #include <string.h>
74
+
75
+ #include <stdbool.h>
76
+
77
+ #include <assert.h>
78
+
79
+
80
+
81
+ typedef long ELEMENT;
82
+
83
+ const char* ELEMENT_FORMAT = "%ld";
84
+
85
+
86
+
87
+ #define STACK_SIZE 100
88
+
89
+
90
+
91
+ typedef struct {
92
+
93
+ ELEMENT body[STACK_SIZE];
94
+
95
+ int size;
96
+
97
+ } Stack;
98
+
99
+
100
+
101
+ void initialize(Stack* stack) {
102
+
103
+ assert( stack );
104
+
105
+ stack->size = 0;
106
+
107
+ }
108
+
109
+
110
+
111
+ /*push関数**/
112
+
113
+ bool push(Stack* stack, ELEMENT x) {
114
+
115
+ assert( stack );
116
+
117
+ if ( stack->size >= STACK_SIZE) {
118
+
119
+ fputs("stack overflow!", stderr);
120
+
121
+ return false;
122
+
123
+ }
124
+
125
+ stack->body[stack->size++] = x;
126
+
127
+ return true;
128
+
129
+ }
130
+
131
+
132
+
133
+ /*pop関数*/
134
+
135
+ bool pop(Stack* stack, ELEMENT* px) {
136
+
137
+ assert( stack );
138
+
139
+ assert( px );
140
+
141
+ if ( stack->size <= 0) {
142
+
143
+ fputs("stack underflow!", stderr);
144
+
145
+ return false;
146
+
147
+ }
148
+
149
+ *px = stack->body[--stack->size];
150
+
151
+ return true;
152
+
153
+ }
154
+
155
+
156
+
157
+
158
+
159
+ bool getnumber(const char* formula, ELEMENT* px) {
160
+
161
+ assert( formula );
162
+
163
+ assert( px );
164
+
165
+ return sscanf(formula, ELEMENT_FORMAT, px) == 1;
166
+
167
+ }
168
+
169
+
170
+
171
+ void calculate(Stack* stack, char* formula) {
172
+
173
+ assert( stack );
174
+
175
+ assert( formula );
176
+
177
+ char* token;
178
+
179
+ for ( token = strtok(formula, " \t\n"); token; token = strtok(NULL, " \t\n") ) {
180
+
181
+ ELEMENT x;
182
+
183
+ ELEMENT a, b;
184
+
185
+ if ( getnumber(token, &x) ) {
186
+
187
+ push(stack, x);
188
+
189
+ } else {
190
+
191
+ if ( false ) ; /* do nothing */
192
+
193
+ else if ( strcmp(token, ".") == 0 ) {
194
+
195
+ pop(stack, &x);
196
+
197
+ }
198
+
199
+ else if ( strcmp(token, "+") == 0 ) {
200
+
201
+ pop(stack, &b);
202
+
203
+ pop(stack, &a);
204
+
205
+ push(stack, a + b);
206
+
207
+ }
208
+
209
+ else if (strcmp(token, "-") == 0) {
210
+
211
+ pop(stack, &b);
212
+
213
+ pop(stack, &a);
214
+
215
+ push(stack, a - b);
216
+
217
+ }
218
+
219
+ else if (strcmp(token, "*") == 0) {
220
+
221
+ pop(stack, &b);
222
+
223
+ pop(stack, &a);
224
+
225
+ push(stack, a * b);
226
+
227
+ }
228
+
229
+ else if (strcmp(token, "/") == 0) {
230
+
231
+ pop(stack, &b);
232
+
233
+ pop(stack, &a);
234
+
235
+ push(stack, a / b);
236
+
237
+ } else {
238
+
239
+ fprintf(stderr, "[%s] unknown\n", token);
240
+
241
+ }
242
+
243
+ }
244
+
245
+ }
246
+
247
+ }
248
+
249
+
250
+
251
+ int main(void) {
252
+
253
+ Stack stack;
254
+
255
+ initialize(&stack);
256
+
257
+
258
+
259
+ int s;
260
+
261
+ char formula[256] = { 0 };
262
+
263
+ printf("数字データの時はスタックに積み、ピリオドの時はスタックから降ろします。(EOFで終了)\n");
264
+
265
+ printf("データ入力の方法を選んでください。\n0..キーボード/1..ファイル:");
266
+
267
+ scanf("%d", &s);
268
+
269
+ FILE* fp = stdin;
270
+
271
+
272
+
273
+ if (s == 1) {
274
+
275
+ fp = fopen("data.txt", "r");
276
+
277
+ if (fp == NULL) {
278
+
279
+ printf("ファイルオープン失敗\n");
280
+
281
+ return 1;
282
+
283
+ }
284
+
285
+ fgets(formula, sizeof(formula), fp);
286
+
287
+ fclose(fp);
288
+
289
+ calculate(&stack, formula);
290
+
291
+ }
292
+
293
+ else if (s == 0) {
294
+
295
+ printf("Input:");
296
+
297
+ gets_s(formula, 32); // 一度空読み
298
+
299
+ fgets(formula, 32, stdin);
300
+
301
+ calculate(&stack, formula);
302
+
303
+ }
304
+
305
+
306
+
307
+ ELEMENT x;
308
+
309
+ pop(&stack, &x);
310
+
311
+ printf("result = ");
312
+
313
+ printf(ELEMENT_FORMAT, x);
314
+
315
+ puts("");
316
+
317
+
318
+
319
+ return 0;
320
+
321
+ }
322
+
323
+ ```

3

追記

2020/06/10 05:07

投稿

episteme
episteme

スコア16614

test CHANGED
@@ -49,3 +49,9 @@
49
49
  あと(こっちの方が重要なんだが)getnumber()から戻ってきたときに formula が
50
50
 
51
51
  更新されないために、最初に現れた数値を延々とpush()し続けてスタック溢れを起こしてます。
52
+
53
+
54
+
55
+ あ...main() で scanf("%s", formula); やってるのもトラブルの原因。
56
+
57
+ これだと空白が読みこまれず、"12 34 +" の入力に対し formulaは"12"となります。

2

微修正

2020/06/09 00:00

投稿

episteme
episteme

スコア16614

test CHANGED
@@ -48,4 +48,4 @@
48
48
 
49
49
  あと(こっちの方が重要なんだが)getnumber()から戻ってきたときに formula が
50
50
 
51
- 更新されないために、最初に現れた数値を延々とpush()し続けてスタック溢れを起こしてます。
51
+ 更新されないために、最初に現れた数値を延々とpush()し続けてスタック溢れを起こしてます。

1

追記

2020/06/08 23:57

投稿

episteme
episteme

スコア16614

test CHANGED
@@ -43,3 +43,9 @@
43
43
  }
44
44
 
45
45
  ```
46
+
47
+
48
+
49
+ あと(こっちの方が重要なんだが)getnumber()から戻ってきたときに formula が
50
+
51
+ 更新されないために、最初に現れた数値を延々とpush()し続けてスタック溢れてを起こしてます。