#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
typedef struct{ //用此结构存储一个单元,一个单元就是用空行(共2个字符ASCII码是13和10)隔开的
char username[BUFSIZ];
char type[BUFSIZ];
char time[BUFSIZ];
char ino[BUFSIZ];
char outo[BUFSIZ];
}bill;
int main(){
FILE *stream,*stream2;
bill u[200]; //为什么数值不能大于200?
char buf[BUFSIZ]; //用buf存储detail.txt中的每一行
char bufusername[BUFSIZ];
char judge[BUFSIZ];
char rawname[200][50]; //you rong yu de bu tong yong hu ming shu zu
char bufname1[BUFSIZ],bufname2[BUFSIZ],bufname3[BUFSIZ],bufname4[BUFSIZ],bufname5[BUFSIZ];//--yong lai gei dan
char bufvalue1[BUFSIZ],bufvalue2[BUFSIZ],bufvalue3[BUFSIZ],bufvalue4[BUFSIZ],bufvalue5[BUFSIZ];//-- tong shang
char *username=" User-Name";
char *accttype=" Acct-Status-Type";
char *accttime=" Acct-Session-Time";
char *acctino=" Acct-Input-Octets";
char *acctouto=" Acct-Output-Octets";
int c=0,i,j,k=0,m=0,n=0,sp,unit,countuname=0,countduname=0;
int totaltime=0,totalino=0,totalouto=0,totalcount=0;
int i1,j1,i2,j2,i3,j3,i4,j4,i5,j5;
int sign=0; //用来标志是否为同一个用户名,1代表同名,0不是
stream=fopen("detail.txt","r");
/*--------ti qu bu tong yong hu ming BEGIN-------
//此while循环目的:把不同的用户名存进rawname[][]里面
//原理:先提取一个用户名(放进judge[]里面),跟保存用户名的二维数组(rawname[][])比较,如果有相同的,设置标志为1,不存入rawname[][];否则标志为0,存入rawname[][]
*/
i=0; //初始化i
while(fgets(buf,sizeof(buf),stream)!=NULL)
{
for(sp=0;sp<strlen(username);sp++)
bufusername[sp]=buf[sp]; //判断该行是否含有" User-Name";
if(strcmp(bufusername,username)==0) //如果是含有User-Name的行(则要取其值)
{
countuname++; //用来计数(含有User-Name的行数)
j=0; //初始化j
k=strlen(bufusername)+3; //初始化k,获取我要取得User-Name值的位置
m=strlen(bufusername)+3; //初始化m,同上,不同的是m用来跟踪第一个buf,给judge赋值(name有重名),k是跟踪第二个buf,给rawname[][]赋值(这时重名的name已经过滤掉)
//-----排除重名的name, BEGIN--------------
//准备工作BEGIN
c=0; //初始化每次(每行)都要从0开始给judge赋值
while(buf[m]!='/0')
{
judge[c]=buf[m];//每次(每行)都要从0给judge赋值,从strlen(bufusername)+3开始给buf赋值,
c++;
m++;
}
judge[c-2]='/0'; //得到我要进行判断的字符串
//printf("%s/n",judge); //局部测试
//准备工作OVER
//BEGIN判断
for(n=0;n<=i;n++) //i代表已经存在于rawname[][]中的字符串数组索引
{
//得到的字符串(judge)和已经存在的字符串进行比较rawname[n]
if(strcmp(judge,rawname[n])==0)
{
sign=1; //代表有相同的名字,不能存入rawname[][]
break; //只要有一个相同的名字就不用比较了,跳出
}
else
sign=0; //可以存入
//printf("%d,%s",n,rawname[i]) //局部测试
}
//OVER判断
//exclusive same name
//printf("%d",sign); //局部测试
//如果没有重名,存入数组rawname
if(sign!=1)
{
while(buf[k]!='/0')//!!!!!强烈注意,不能用while(buf[i]!=" "),因为在linux下鞘枪獗甑奈恢?,而不是空格,我被迷惑了
{
rawname[i][j]=buf[k]; //道理同取judge
j++; //
k++;
}
rawname[i][j-2]='/0';
//printf("%d= %s/n",i,rawname[i]); //局部测试
countduname++; //wu rong yu bu tong yong hu ming shu zu zong gong ge shu
i++; //如果成功添加了用户名,i自增
}
}
}
char rawdname[countduname][50]; //wu you rong yu de bu tong yong hu ming shu zu
for(i=0;i<countduname;i++)
strcpy(rawdname[i],rawname[i]);
//for(i=0;i<countduname;i++)
//printf("%s/n",rawdname[i]);
/*-----------ti qu bu tong yong hu ming OVER-------------*/
stream=fopen("detail.txt","r");
//yin wei wen jian zhi zhen dao le zui hou,suo yi yao chong xin dai kai detail.txt
//------此处while循环目的是分别把每一个单元放到结构体数组struct bill u[]中,BEGIN---//
unit=0;
while(fgets(buf,sizeof(buf),stream)!=NULL) //针对每一行进行判断
{
if(buf[0]==13) //如果每一行的第一个字符(ASCII码)是13,那就意味着一个新的单元的开始
unit++; //新的单元开始,结构索引值递增
else //如果不是,说明在一个单元内
{
//--------获取用户名BEGIN---------
for(i1=0;i1<strlen(username);i1++) //我要找到的目标行是User-Name
bufname1[i1]=buf[i1];
if(strcmp(bufname1,username)==0) //开始获取User-Name值
{
i1=strlen(bufname1)+3; //初始化i1为User-Name值的位置,+3是为了跳过2个空格和一个'='
j1=0; //初始化j1
while(buf[i1]!='/0')
{ //获取User-Name值
bufvalue1[j1]=buf[i1];
i1++;
j1++;
}
bufvalue1[j1-2]='/0';
strcpy(u[unit].username,bufvalue1); //给某一个单元的username赋值
//printf("uname=%s/n",u[unit].username); //局部测试
}
//---------获取用户名OVER--------
//--------获取类型BEGIN---------
for(i2=0;i2<strlen(accttype);i2++)
bufname2[i2]=buf[i2];
if(strcmp(bufname2,accttype)==0) //get Acct-Type's value
{
i2=strlen(bufname2)+3;
j2=0;
while(buf[i2]!='/0')
{//get type value
bufvalue2[j2]=buf[i2];
i2++;
j2++;
}
bufvalue2[j2-2]='/0';
strcpy(u[unit].type,bufvalue2);
//printf("type=%s/n",u[unit].type);
}
//---------获取类型OVER--------
//--------获取时间BEGIN---------
for(i3=0;i3<strlen(accttime);i3++)
bufname3[i3]=buf[i3];
if(strcmp(bufname3,accttime)==0) //get Acct-Type's value
{
i3=strlen(bufname3)+3;
j3=0;
while(buf[i3]!='/0')
{//get type value
bufvalue3[j3]=buf[i3];
i3++;
j3++;
}
bufvalue3[j3-2]='/0';
strcpy(u[unit].time,bufvalue3); //gei dan yuan nei de "username" fu zhi
//printf("time=%s/n",u[unit].time);
}
//---------获取时间OVER--------//
//--------获取流入量BEGIN---------//
for(i4=0;i4<strlen(acctino);i4++)
bufname4[i4]=buf[i4];
if(strcmp(bufname4,acctino)==0) //get Acct-Type's value
{
i4=strlen(bufname4)+3;
j4=0;
while(buf[i4]!='/0')
{//get type value
bufvalue4[j4]=buf[i4];
i4++;
j4++;
}
bufvalue4[j4-2]='/0';
strcpy(u[unit].ino,bufvalue4); //gei dan yuan nei de "username" fu zhi
//printf("time=%s/n",u[unit].time);
}
//---------获取流入量OVER--------//
//--------获取流出量BEGIN---------//
for(i5=0;i5<strlen(acctouto);i5++)
bufname5[i5]=buf[i5];
if(strcmp(bufname5,acctouto)==0) //get Acct-Type's value
{
i5=strlen(bufname5)+3;
j5=0;
while(buf[i5]!='/0')
{//get type value
bufvalue5[j5]=buf[i5];
i5++;
j5++;
}
bufvalue5[j5-2]='/0';
strcpy(u[unit].outo,bufvalue5); //gei dan yuan nei de "username" fu zhi
//printf("time=%s/n",u[unit].time);
}
//---------获取流出量OVER--------//
}
}
//------此处while循环目的是分别把每一个单元放到结构体数组struct bill u[] OVER----//
//for(i=0;i<160;i++)
//printf("username=%-15s,type=%-5s,time=%-5s,ino=%-5s,outo=%-5s/n",u[i].username,u[i].type,u[i].time,u[i].ino,u[i].outo);
//printf("%d",unit);
//----ji fei BEGIN----------//
for(i=0;i<countduname;i++)
{
totaltime=0; //qing 0
totalino=0; //qing 0
totalouto=0;
for(j=0;j<unit;j++)
{
if(strcmp(rawdname[i],u[j].username)==0)
{
totaltime+=atoi(u[j].time);
totalino+=atoi(u[j].ino);
totalouto+=atoi(u[j].outo);
}
}
stream2=fopen("result","a");
dup2(fileno(stream2),STDOUT_FILENO);
printf("%s de totaltime is %d,totalino is %d,totalouto is %d/n",rawdname[i],totaltime,totalino,totalouto);
//stream2=fopen("result","a");
//fputs("%s de totaltime is %d,totalino is %d,totalouto is %d/n",rawdname[i],totaltime,totalino,totalouto);
}
//----ji fei OVER---------//
}