想打開一個日志檔案并把它存到結構體中,,但是檔案有很多條,能在定義結構體時通過for回圈把所有資訊存到items里嗎?
#include<stdio.h>
#include<string.h>
struct record//record為結構體名
{
char method[255];
char ip[255];
char protocol[255];
char time[255];
char add[255];
char port[255];
char page[255];
int status;
char exploer_info[255];
struct prams
{
char key[255];
char value[255];
};
int prams_cnt;
};//定義結構體
int main(void)
{
FILE *fp;
fp=fopen("access.log","r+");//打開檔案
if(!fp)
{
printf("false\n");
return -1;//直接回傳
}
else{
printf("true\n");
}//判斷檔案是否成功打開
struct record items[255];//所有記錄
int items_cnt=0;//記錄數
char line[2048];
int i=0,x,j,j_pos,j_pos1;
int lines=0;
int pos[9],pos1[9];
char s='[';
char s1=']';
struct record rec;//定義結構體變數
printf("日志分析:\n");
while((fgets(line,2048,fp))!=NULL)
{
x=strlen(line);
j_pos=0,j_pos1=0;
for(j=0;j<x;j++)
{
if(line[j]==s)//此處為'['開始的位置
{
pos[j_pos]=j;
j_pos++;
}
if(line[j]==s1)//']'結束的位置
{
pos1[j_pos1]=j;
j_pos1++;
}
}
//strncpy_s函式的使用strncpy_s(char *str2,int size2,char *str1,int size1);
strncpy_s(items[s].method,sizeof(items[s].method),line+pos[0]+1,pos1[0]-pos[0]-1);
strncpy_s(items[s].ip,sizeof(items[s].ip),line+pos[1]+1,pos1[1]-pos[1]-1);
strncpy_s(items[s].protocol,sizeof(items[s].protocol),line+pos[2]+1,pos1[2]-pos[2]-1);
strncpy_s(items[s].time,sizeof(items[s].time),line+pos[3]+1,pos1[3]-pos[3]-1);
strncpy_s(items[s].add,sizeof(items[s].add),line+pos[4]+1,pos1[4]-pos[4]-1);
strncpy_s(items[s].page,sizeof(items[s].page),line+pos[5]+1,pos1[5]-pos[5]-1);
strncpy_s(items[s].port,sizeof(items[s].port),line+pos[6]+1,pos1[6]-pos[6]-1);
strncpy_s(items[s].status,sizeof(items[s].status),line+pos[7]+1,pos1[7]-pos[7]-1);
strncpy_s(items[s].exploer_info,sizeof(items[s].exploer_info),line+pos[8]+1,pos1[8]-pos[8]-1);
//結構體成員賦值
}
/*if(line[strlen(line)-1]=='\n')
{
lines++;
}*/
//int maxi=0,maxn=0;
int fclose(FILE *fp);
fp=fopen("access.log","r+");
int n=0,m=0;
while(fgets(line,2048,fp)!=NULL)
{
puts(line);
n++;
if(strncmp(line,"[GET]",5)==0)
{
m++;
}//比較兩字串,相等時strncmp函式值回傳0,計數
}//輸出日志檔案內容并統計計數
printf("輸出GET請求所占比例:%f\n",1.0*m/n);//輸出所占百分比;
int maxi=0,maxn=0;
char arr[255]={0};
char vis[255]={0};
/*for(i=0;i<line[i];i++)
{
if(maxn<vis[i])
{
maxn=vis[i];
maxi=i;
}
}*/
for(i=0;i<line[i];i++)
{
arr[items[i].status]++;
vis[items[i].status]=1;
if(maxn<vis[i])
{
maxn=vis[i];
maxi=i;
}
}
printf("%lf\n",1.0*arr[i]++/i);
printf("%lf",maxi);
int fclose(FILE *fp);//關閉檔案
return 0;
}
uj5u.com熱心網友回復:
僅供參考://NAME: essaie bla bla
//DIMENSION: 8
//DATA
//1 14 15
//2 11 10
//3 6 4
//4 7 13
//5 9 21
//6 19 3
//7 1 5
//8 8 8
//EOF
//
// 文本檔案中可能還含有其他內容,但是需要用到的內容即以上
//比如data.txt:
//NAME: essaie bla bla
//其它內容
//DIMENSION: 8
//其它內容
//DATA
//其它內容
//1 14 15
//其它內容
//2 11 10
//其它內容
//3 6 4
//其它內容
//4 7 13
//其它內容
//5 9 21
//其它內容
//6 19 3
//其它內容
//7 1 5
//其它內容
//8 8 8
//其它內容
//EOF
// 目標是要獲取NAME后字串,DIMENSION后數值,以及DATA以下的數值
// 其中NAME就是隨便個字句,DIMENSION是城市數量,DATA以下是城市編號,X坐標,Y坐標
// 所有的這些將賦值給一個事先定義好的結構
#include <stdio.h>
#include <string.h>
#define MAXCPL 80 //每行最大字符數
#define MAXCITY 100 //每組資料中DATA最多項數,DIMENSION的最大值
#define MAXNAMEL 32 //NAME最大長度
struct S {
char NAME[MAXNAMEL+1];
int DIMENSION;
struct D {
int NO;
int X;
int Y;
} DATA[MAXCITY];
} s;
FILE *f;
int st,n,i;
char ln[MAXCPL];
int main() {
f=fopen("data.txt","r");
if (NULL==f) {
printf("Can not open file data.txt!\n");
return 1;
}
st=0;
n=0;
while (1) {
if (NULL==fgets(ln,MAXCPL,f)) break;
if (st==0) {
if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;
} else if (st==1) {
if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;
} else if (st==2) {
if (0==strcmp(ln,"DATA\n")) st=3;
} else if (st==3) {
if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {
n++;
if (n>=MAXCITY || n>=s.DIMENSION) break;
}
}
}
fclose(f);
printf("s.NAME=[%s]\n",s.NAME);
printf("s.DIMENSION=%d\n",s.DIMENSION);
for (i=0;i<n;i++) {
printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);
}
return 0;
}
//s.NAME=[essaie bla bla]
//s.DIMENSION=8
//s.DATA[0].NO,X,Y=1,14,15
//s.DATA[1].NO,X,Y=2,11,10
//s.DATA[2].NO,X,Y=3,6,4
//s.DATA[3].NO,X,Y=4,7,13
//s.DATA[4].NO,X,Y=5,9,21
//s.DATA[5].NO,X,Y=6,19,3
//s.DATA[6].NO,X,Y=7,1,5
//s.DATA[7].NO,X,Y=8,8,8
uj5u.com熱心網友回復:
內容很多,建議分類,并且找到資訊型別一樣的,并在結構體里定義對應的元素,根據資訊量的條數來定結構體變數的大小或結構體陣列的大小uj5u.com熱心網友回復:
看到樓主仍然堅持嵌套定義結構體(這是個編譯錯誤),就沒興趣繼續看下去了。一般地說,要在結構體陣列和檔案之間互動,還是使用二進制檔案方便一些。
對于樓主面臨的分析日志,由于檔案長度不定,另外全部讀入記憶體也沒有演算法上的必要,因此建議還是用我的風格,讀一行統計一行,扔掉,讀下一行。
這樣一來,用不用結構體不是關鍵,或者說結構體就多余了。
最后,如果是作業需要,那么建議找個開源軟體代替syslog,日志入庫,你要分析什么的可以上SQL,很香的。
uj5u.com熱心網友回復:
早些年有個syslog-ng是用來日志入庫的,近幾年流行啥就不知道了,沒有跟蹤。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/263936.html
標籤:C語言
上一篇:double型別用scanf函式時格式符%f和%lf不一樣結果?有沒有懂得解釋一下
下一篇:C語言學習路線圖
