回答編集履歴

1

m

2020/11/18 17:45

投稿

yumetodo
yumetodo

スコア5852

test CHANGED
@@ -95,3 +95,267 @@
95
95
 
96
96
 
97
97
  のように結果が得られます。つまり、全般に配列へのアクセスに問題があります。
98
+
99
+
100
+
101
+
102
+
103
+ 多少書き直してデバッグログも仕込んでみました
104
+
105
+
106
+
107
+ ```c
108
+
109
+ #include <stdio.h>
110
+
111
+ #include <stdlib.h>
112
+
113
+ #include <string.h>
114
+
115
+
116
+
117
+ #define N 50
118
+
119
+
120
+
121
+ struct LOG {
122
+
123
+ long time;
124
+
125
+ char server_name[N];
126
+
127
+ char result[N];
128
+
129
+ };
130
+
131
+
132
+
133
+ void printTime(long kikan) {
134
+
135
+ char kikan2[14];
136
+
137
+ sprintf(kikan2, "%ld", kikan);
138
+
139
+ int len = strlen(kikan2);
140
+
141
+ long sec, min, hour, day, month, year;
142
+
143
+ year = kikan / 10000000000;
144
+
145
+ month = (kikan / 1000000) % 100;
146
+
147
+ day = (kikan / 10000) % 100;
148
+
149
+ hour = (kikan / 100) % 100;
150
+
151
+ min = kikan / 100;
152
+
153
+ sec = kikan % 100;
154
+
155
+
156
+
157
+ if (len <= 2) {
158
+
159
+ printf("故障期間は%ld秒です\n", sec);
160
+
161
+ } else if (len <= 4) {
162
+
163
+ printf("故障期間は%ld分%ld秒です\n", min, sec);
164
+
165
+ } else if (len <= 6) {
166
+
167
+ printf("故障期間は%ld時%ld分%ld秒です\n", hour, min, sec);
168
+
169
+ } else if (len <= 8) {
170
+
171
+ printf("故障期間は%ld日%ld時%ld分%ld秒です\n", day, hour, min, sec);
172
+
173
+ } else if (len <= 10) {
174
+
175
+ printf("故障期間は%ld月%ld日%ld時%ld分%ld秒です\n", month, day, hour, min, sec);
176
+
177
+ } else if (len <= 14) {
178
+
179
+ printf("故障期間は%ld年%ld月%ld日%ld時%ld分%ld秒です\n", year, month, day, hour, min, sec);
180
+
181
+ }
182
+
183
+ }
184
+
185
+
186
+
187
+ int main() {
188
+
189
+ FILE *fp;
190
+
191
+ struct LOG log[30];
192
+
193
+
194
+
195
+ char s[N][N], *cp, handan_name[N];
196
+
197
+
198
+
199
+ const char *sikiri = ",";
200
+
201
+ long handan_time = 0, kikan;
202
+
203
+ int i = 0, len = 0, ct = 0; // ctによって一度のエラーにつき一回のみと判断
204
+
205
+
206
+
207
+ fp = fopen("server.txt", "r");
208
+
209
+
210
+
211
+ while (fgets(s[i], N, fp) != NULL) {
212
+
213
+ printf("Debug(line %d): i=%d\n", __LINE__, i);
214
+
215
+ cp = strtok(s[i], sikiri);
216
+
217
+ log[i].time = atol(cp); //ここで時間を挿入、文字列から数に変換
218
+
219
+ int c = 0;
220
+
221
+ while (NULL != (cp = strtok(NULL, sikiri))) {
222
+
223
+ if (c == 0) {
224
+
225
+ strcpy(log[i].server_name, cp); //ここでサーバーの名前を挿入
226
+
227
+ c++;
228
+
229
+
230
+
231
+ if (strcmp(&handan_name[len - 1], "1") && strncmp(handan_name, log[i].server_name, 8) == 0 &&
232
+
233
+ ct == 1) { // if(故障していたら)ここでサーバーの名前がかぶってないか判断
234
+
235
+ kikan = log[i].time - handan_time;
236
+
237
+ printTime(kikan);
238
+
239
+ ct--;
240
+
241
+ } else if (strcmp(&handan_name[len - 1], "2") && strncmp(handan_name, log[i].server_name, 9) == 0 && ct == 1) {
242
+
243
+ kikan = log[i].time - handan_time;
244
+
245
+ printTime(kikan);
246
+
247
+ ct--;
248
+
249
+ }
250
+
251
+ }
252
+
253
+
254
+
255
+ if (cp != NULL && c == 1) {
256
+
257
+ strcpy(log[i].result, cp); //ここで結果を挿入
258
+
259
+ if (strncmp(log[i].result, "-", 1) == 0 && ct == 0) {
260
+
261
+ printf("サーバー%sが故障状態です\n", log[i].server_name); //サーバーが故障しているか判断
262
+
263
+ len = strlen(log[i].server_name);
264
+
265
+ handan_time = log[i].time;
266
+
267
+ strcpy(handan_name, log[i].server_name);
268
+
269
+ ct++;
270
+
271
+ }
272
+
273
+ }
274
+
275
+ }
276
+
277
+ i++;
278
+
279
+ }
280
+
281
+
282
+
283
+ fclose(fp);
284
+
285
+ return 0;
286
+
287
+ }
288
+
289
+ ```
290
+
291
+
292
+
293
+ 同様に実行すると
294
+
295
+
296
+
297
+ ```
298
+
299
+ Debug(line 53): i=0
300
+
301
+ main.cpp:62:21: runtime error: index -1 out of bounds for type 'char [50]'
302
+
303
+ SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.cpp:62:21 in
304
+
305
+ main.cpp:67:28: runtime error: index -1 out of bounds for type 'char [50]'
306
+
307
+ SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior main.cpp:67:28 in
308
+
309
+ Debug(line 53): i=1
310
+
311
+ Debug(line 53): i=2
312
+
313
+ Debug(line 53): i=3
314
+
315
+ Debug(line 53): i=4
316
+
317
+ Debug(line 53): i=5
318
+
319
+ Debug(line 53): i=6
320
+
321
+ Debug(line 53): i=7
322
+
323
+ Debug(line 53): i=8
324
+
325
+ サーバー10.20.30.1/16が故障状態です
326
+
327
+ Debug(line 53): i=9
328
+
329
+ 故障期間は1秒です
330
+
331
+ Debug(line 53): i=10
332
+
333
+ サーバー10.20.30.1/16が故障状態です
334
+
335
+ Debug(line 53): i=11
336
+
337
+ 故障期間は7分6秒です
338
+
339
+ Debug(line 53): i=12
340
+
341
+ サーバー10.20.30.1/16が故障状態です
342
+
343
+ Debug(line 53): i=13
344
+
345
+ 故障期間は10秒です
346
+
347
+ Debug(line 53): i=14
348
+
349
+ サーバー192.168.1.1/24が故障状態です
350
+
351
+ Debug(line 53): i=15
352
+
353
+ 故障期間は5分90秒です
354
+
355
+ Debug(line 53): i=16
356
+
357
+ ```
358
+
359
+
360
+
361
+ 56行目で初期化されている変数`c`に着目すると、`c`が0となるのは初めてループに入ったときのみとなります。このとき`len`は確実に`0`です。にも関わらす`len -1`のようにアクセスしているため、配列外参照になっています。これは多分ロジックがおかしいのではないのですかね。