プログラムの内容
c言語で、ファイルから読み取ったデータをもとにサーバーが動いているかどうかを確認するプログラムを作成しています。
読み込むファイル
20201019133124,10.20.30.1/16,-
20201019133125,10.20.30.2/16,1
20201019133134,192.168.1.1/24,10
20201019133135,192.168.1.2/24,5
20201019133224,10.20.30.1/16,522
20201019133225,10.20.30.2/16,1
20201019133234,192.168.1.1/24,8
20201019133235,192.168.1.2/24,15
20201019133324,10.20.30.1/16,-
20201019133325,10.20.30.2/16,3
20201019134510,192.168.1.1/24,1
20201019135050,192.168.1.2/24,15
20201019135051,10.20.30.1/16,-
20201019135052,10.20.30.2/16,3
20201019135055,10.20.30.1/16,2
20201019135100,10.20.30.2/16,2
20201019135510,192.168.1.1/24,-
20201019135550,192.168.1.2/24,15
20201019135600,192.168.1.1/24,-
20201019135601,192.168.1.2/24,15
20201019135610,192.168.1.1/24,1
20201019135611,192.168.1.2/24,15
左から<確認日時>,<サーバアドレス>,<応答結果>という並びになっています。
応答結果で-が返ってきた場合にサーバー故障とみなすようになっています。
このファイルを読み込み、故障状態のアドレスとそのアドレスの故障期間を出力するプログラムを作りたいと考えています。
(故障期間は、最初に-が出てから次にちゃんとしたping値がかえるまでの期間)
該当のソースコード
c
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <stdbool.h> 5 6#define N 50 7struct HANDAN{ 8 char handan_name[N]; 9 int kaisuu; 10 long time; 11 bool count; 12}; 13 14struct LOG{ 15 long time; 16 char server_name[N]; 17 char result[N]; 18}; 19 20void printTime(long kikan){ 21 char kikan2[14]; 22 sprintf(kikan2,"%ld",kikan); 23 int len = strlen(kikan2); 24 long sec,min,hour,day,month,year; 25 year = kikan/10000000000; 26 month = (kikan/1000000)%100; 27 day = (kikan/10000)%100; 28 hour = (kikan/100)%100; 29 min = kikan/100; 30 sec = kikan%100; 31 32 if(sec>=60){ 33 sec = sec-60; 34 min = min+1; 35 } 36 if(min>=60){ 37 sec = min-60; 38 hour = hour+1; 39 } 40 //printf("%ld年%ld月%ld日%ld時%ld分です\n",year,month,day,hour,min); 41 //printf("kikan is %ld\n",kikan); 42 43 if(len<=2){ 44 printf("故障期間は%ld秒です\n",sec); 45 }else if(len<=4){ 46 printf("故障期間は%ld分%ld秒です\n",min,sec); 47 }else if(len<=6){ 48 printf("故障期間は%ld時%ld分%ld秒です\n",hour,min,sec); 49 }else if(len<=8){ 50 printf("故障期間は%ld日%ld時%ld分%ld秒です\n",day,hour,min,sec); 51 }else if(len<=10){ 52 printf("故障期間は%ld月%ld日%ld時%ld分%ld秒です\n",month,day,hour,min,sec); 53 }else if(len<=14){ 54 printf("故障期間は%ld年%ld月%ld日%ld時%ld分%ld秒です\n",year,month,day,hour,min,sec); 55 } 56} 57 58 59 60int main(){ 61 FILE *fp; 62 struct HANDAN han[N]; 63 struct LOG log[N]; 64 char s[N][N],*cp; 65 char name[4][15]={"10.20.30.1/16","10.20.30.2/16","192.168.1.1/24","192.168.1.2/24"}; 66 const char *sikiri=","; 67 long handan_time=0,kikan; 68 int i = 0,j = 0,h=0; 69 int kaisuu[4] = {}; 70 bool count[N]={};//countによって故障したかどうか判断 71 72 fp = fopen("server.txt","r"); 73 74 while(fgets(s[i],N,fp)!=NULL){ 75 cp = strtok(s[i],sikiri); 76 log[i].time=atol(cp);//ここで時間を挿入、文字列から数に変換 77 int c=0; 78 while(cp!=NULL){ 79 cp = strtok(NULL,sikiri); 80 if(cp!=NULL&&c==0){ 81 strcpy(log[i].server_name,cp); //ここでサーバーの名前を挿入 82 c++; 83 84 for(h=0;h<=j;h++){ 85 if(han[h].count==true){ //if(故障していたら)故障状況をプリント 86 if(strcmp(han[h].handan_name,log[i].server_name)==0){ 87 kikan=log[i].time-han[h].time; 88 printf("サーバー%sが故障状態です\n",han[h].handan_name); 89 printf("log.time is %ld\nhandan is %ld\n",log[i].time,han[h].time); 90 printTime(kikan); 91 han[h].count = false; 92 93 } 94 } 95 96 } 97 98 } 99 100 if(cp!=NULL&&c==1){ 101 strcpy(log[i].result,cp);//ここで結果を挿入 102 if(strncmp(log[i].result,"-",1)==0){ //1."-"かどうか 103 for(h=0;h<4;h++){//回数計算 104 if(strcmp(log[i].server_name,name[h])==0){ //入力された値がどれかと一緒ならkaisuuを+1する 105 if(kaisuu[h]==0){ //2.一回目か 106 strcpy(han[j].handan_name,log[i].server_name); 107 han[j].time = log[i].time; 108 } 109 kaisuu[h]++; 110 } 111 } 112 //printf("%d %d %d %d\n",kaisuu[0],kaisuu[1],kaisuu[2],kaisuu[3]); 113 }else{ 114 for(h=0;h<=j;h++){ 115 if(strcmp(han[h].handan_name,log[i].server_name)==0){//名前が以前に出てきていないか確認 116 han[h].count=true; 117 } 118 } 119 } 120 } 121 j++; 122 } 123 124 i++; 125 } 126 127 fclose(fp); 128 return 0; 129}
発生している問題
実行してみると、以下のように出力されます。
サーバー10.20.30.1/16が故障状態です log.time is 20201019133324 handan is 20201019133124 故障期間は2分0秒です サーバー10.20.30.1/16が故障状態です log.time is 20201019135051 handan is 20201019133124 故障期間は19分27秒です サーバー10.20.30.1/16が故障状態です log.time is 20201019135055 handan is 20201019133124 故障期間は19分31秒です サーバー192.168.1.1/24が故障状態です log.time is 20201019135610 handan is 20201019135510 故障期間は1分0秒です
出力された結果を見ると、応答結果で-が出た後、応答結果が正常かどうかは関係なく同じアドレスのログを一つ飛ばしで参照されてしまいます。
例)
サーバー10.20.30.1/16が故障状態です
と出力された後、本当ならば
20201019133224,10.20.30.1/16,522
のログを参照して変数に代入したいのですが、
20201019133324,10.20.30.1/16,-
のログを参照してしまいます。
どう変更すればうまく参照できるようになるのでしょうか。
言葉足らずな説明で申し訳ありません。
