MOOC清华《程序设计基础》第7章:统计在线时长
来源:互联网 发布:java怎么调用外部接口 编辑:程序博客网 时间:2024/05/17 22:08
#include <iostream>#include <fstream> //包含文件操作的头文件 #include <cstring> //字符串操作头文件 using namespace std;//added in 3.0, 时间类型的结构定义struct Time_t{int year, month, day;int hour, minute, second;};//added in 3.0, 计算时长的函数声明int TimeDifference(Time_t, Time_t); int main(){//ifstream fin("log.txt"); //ifstream表示input file stream//上面这一行也可以写成如下两行:ifstream fin;fin.open("log.txt"); int user_count = 0; char ids[600][20]; //记录所有的编号 bool online[600]; //added in 3.0, 记录在线状态Time_t last_on[600]; //added in 3.0, 记录上次登录时间int secs[600]; //added in 3.0, 累计在线秒数 while(!fin.eof()) //eof表示end of file{Time_t t;char tmp, id[20], operation[10];//added in 3.0, 获取文本文件中的一行(结构体版本) fin >> t.year >> tmp >> t.month >> tmp >> t.day; // 2015/4/21fin >> t.hour >> tmp >> t.minute >> tmp >> t.second; // 11:16:16fin >> id; // 40dbae14f777cddfin >> operation; // LOGINint found = -1;//判断是否是新用户 for(int i = 0; i < user_count; i++)if(strcmp(id, ids[i]) == 0){found = i;break;}//如果是新用户,记录新用户的登录状态,并记录上次登录时间 if(found == -1) //debug记录:千万不要写掉了一个等号 {strcpy(ids[user_count], id); //added in 3.0, 记录新用户的登录状态 if(strcmp(operation, "LOGIN") == 0){online[user_count] = true; //登录状态改为“在线” last_on[user_count] = t; //记录上次登录时间//特别注意:这里t为结构类型,它与普通类型一样,也是能赋值给一个数组元素的! }elseonline[user_count] = false;user_count++;}//如果不是新用户,修改登录状态,记录在线时长 else{if(strcmp(operation, "LOGIN") == 0) //如果当前操作是登录操作 {if(!online[found]) //而且当前的状态是不在线 {online[found] = true; //就把当前状态改为在线 last_on[found] = t; //并把登录时间记下来 }}else //否则就是登出操作{if(online[found]) //并且当前状态是在线 {online[found] = false; //就把当前状态改为不在线 //并调用函数,计算两个时刻之差secs[found] += TimeDifference(last_on[found], t); }} }} fin.close(); //关闭文件//added in 3.0, 输出每一个用户的在线时长for(int i = 0; i < user_count; i++) cout << ids[i] << " " << secs[i] << endl; return 0; }//added in 3.0, 计算时间差,已知只会出现2015年内的时间//若要计算位于不同年的时刻之间的时间差,则还需考虑int型数据的最大容量,防止溢出 int TimeDifference(Time_t s, Time_t t) {int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int day_count = t.day - s.day;for(int i = s.month; i < t.month; i++)day_count += days[i - 1]; //减1的目的是数组下标与实际的月份数相一致 int result = day_count * 60 * 60 * 24;result += (t.hour - s.hour) * 60 * 60;result += (t.minute - s.minute) * 60;result += (t.second - s.second);return result;}
运行结果:
可以估计出,整个控制台缓冲区并没有500多行,有一些靠前面的输出结果被掐掉了。为解决这个问题,可以把输出结果输出到另一个文件中。
#include <iostream>#include <fstream> //包含文件操作的头文件 #include <cstring> //字符串操作头文件 using namespace std;//added in 3.0, 时间类型的结构定义struct Time_t{int year, month, day;int hour, minute, second;};//added in 3.0, 计算时长的函数声明int TimeDifference(Time_t, Time_t); int main(){//ifstream fin("log.txt"); //ifstream表示input file stream//上面这一行也可以写成如下两行:ifstream fin;fin.open("log.txt"); int user_count = 0; char ids[600][20]; //记录所有的编号 bool online[600]; //added in 3.0, 记录在线状态Time_t last_on[600]; //added in 3.0, 记录上次登录时间int secs[600]; //added in 3.0, 累计在线秒数 while(!fin.eof()) //eof表示end of file{Time_t t;char tmp, id[20], operation[10];//added in 3.0, 获取文本文件中的一行(结构体版本) fin >> t.year >> tmp >> t.month >> tmp >> t.day; // 2015/4/21fin >> t.hour >> tmp >> t.minute >> tmp >> t.second; // 11:16:16fin >> id; // 40dbae14f777cddfin >> operation; // LOGINint found = -1;//判断是否是新用户 for(int i = 0; i < user_count; i++)if(strcmp(id, ids[i]) == 0){found = i;break;}//如果是新用户,记录新用户的登录状态,并记录上次登录时间 if(found == -1) //debug记录:千万不要写掉了一个等号 {strcpy(ids[user_count], id); //added in 3.0, 记录新用户的登录状态 if(strcmp(operation, "LOGIN") == 0){online[user_count] = true; //登录状态改为“在线” last_on[user_count] = t; //记录上次登录时间//特别注意:这里t为结构类型,它与普通类型一样,也是能赋值给一个数组元素的! }elseonline[user_count] = false;user_count++;}//如果不是新用户,修改登录状态,记录在线时长 else{if(strcmp(operation, "LOGIN") == 0) //如果当前操作是登录操作 {if(!online[found]) //而且当前的状态是不在线 {online[found] = true; //就把当前状态改为在线 last_on[found] = t; //并把登录时间记下来 }}else //否则就是登出操作{if(online[found]) //并且当前状态是在线 {online[found] = false; //就把当前状态改为不在线 //并调用函数,计算两个时刻之差secs[found] += TimeDifference(last_on[found], t); }} }} fin.close(); //关闭文件//added in 3.1, 把每一个用户的在线时长输出到文件ofstream fout;fout.open("times.txt"); for(int i = 0; i < user_count; i++) fout << ids[i] << " " << secs[i] << endl; fout.close();return 0; }//added in 3.0, 计算时间差,已知只会出现2015年内的时间//若要计算位于不同年的时刻之间的时间差,则还需考虑int型数据的最大容量,防止溢出 int TimeDifference(Time_t s, Time_t t) {int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int day_count = t.day - s.day;for(int i = s.month; i < t.month; i++)day_count += days[i - 1]; //减1的目的是数组下标与实际的月份数相一致 int result = day_count * 60 * 60 * 24;result += (t.hour - s.hour) * 60 * 60;result += (t.minute - s.minute) * 60;result += (t.second - s.second);return result;}
可见控制台窗口已经没有输出了,输出到了exe文件根目录下的文本文件中。
写入文件的核心代码是这几行:
//added in 3.1, 把每一个用户的在线时长输出到文件ofstream fout;fout.open("times.txt"); for(int i = 0; i < user_count; i++) fout << ids[i] << " " << secs[i] << endl; fout.close();经测试,文件名不能命名为带路径名的形式,否则无法输出。不过,也许需要包含某个头文件也未可知,以后学到再说吧。
阅读全文
0 0
- MOOC清华《程序设计基础》第7章:统计在线时长
- MOOC清华《程序设计基础》第7章:统计活跃用户数
- MOOC清华《程序设计基础》第7章:读文件操作
- MOOC清华《程序设计基础》第2章第2题:求圆周长2
- MOOC清华《程序设计基础》第4章:筛法求素数
- MOOC清华《程序设计基础》第4章:筛法数人数
- MOOC清华《程序设计基础》第5章:归并排序
- MOOC清华《程序设计基础》第5章:青蛙过河问题
- MOOC清华《程序设计基础》第7章第1题:用结构体计算天数
- MOOC清华《程序设计基础》期末考试第3题:统计高考录取人数与录取最低分
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v1.0(采用迭代器模式)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v2.0(采用迭代器、容器、模板方法)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v3.0(自定义数据类型)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v4.0(定义抽象结构)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v5.1(“记住”及格分数线)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v5.2(用文件输入及格线)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v5.3(采用函数对象)
- MOOC清华《面向对象程序设计》第7章:统计考试及格率v5.4(单科及格与总分及格)
- Spring bean的生命周期(初步)
- 【贪心】codeforces 825D Suitable Replacement
- Hibernate Validator参数校验
- 素数筛选:HDU2710-Max Factor
- (2017多校训练第二场)HDU
- MOOC清华《程序设计基础》第7章:统计在线时长
- 多线程与多进程 执行效率
- 链接收藏3
- Struts转换器和错误提示
- 记一次获得 3 倍性能的 Go 程序优化实践,及 on-cpu / off-cpu 火焰图的使用
- CSU 1562Fun House
- css两列布局
- 免费免备案空间集合
- Hdu 1512 Monkey King 左偏树 解题报告