目录
更新内容
使用flush()强制输出缓冲区内容,解决了文本文件内容不更新的问题
部分漏洞
1.窗口名过长会无法关闭
2.只要有一个fshow对象不自动关闭窗口,析构时所有fshow对象都无法删除对应文本文件。可能是window把所有shower.exe判为同个进程?从而只要有一个没结束,就不释放相应文件的权限?
示例代码
#include <iostream>
#include "fshow.h"
int main() {
fshow a("a");
fshow b("b");
fshow c;
c << "123" << 456;
for(int i=1;i<2000000;++i)
{
a<<i<<'\n';
b<<-i<<'\n';
if(i%10==0){
a.clean();
b.clean();
}
}
system("pause");
return 0;
}
功能实现的相关代码
fshow.h
#ifndef FSHOW_H
#define FSHOW_H
#include<iostream>
#include<fstream>
#include<sstream>
#include<windows.h>
using namespace std;
class fshow
{
static int cnt;
string name;
ofstream ot;
bool autoClose;
bool autoDel;
public:
// name为对应文件和窗口的名字,
// autoCls指定该显示窗口是否自动关闭
// autoDl指定对应文本文件是否自动删除 (前提条件为对应窗口自动关闭)
fshow(string name="",bool autoCls=1,bool autoDl=1);
~fshow();
template<class T>
fshow& operator<<(T toShw)
{
//cout <<name<< ot.is_open()<<'\n';
ot<<toShw;
ot.flush();
//cout<<toShw<<'\n';
return *this;
}
void clean();
};
#endif
fshow.cpp
#include "fshow.h"
int fshow::cnt=0;
fshow::fshow(string nam, bool autoCls, bool autoDl)
:autoClose(autoCls),autoDel(autoDl)
{
//cout<<"constructing\n";
//cout << name << ' ' << autoClose << ' ' << autoDel << '\n';
++cnt;
if(cnt%10==0){
cout<<"已新建多个窗口,为预防不受控新建,自动暂停\n";
system("pause");
}
if(nam==""){
stringstream ss;
ss<<cnt;
ss>>nam;
}
name=nam;
string filename=".\\fshowOutput\\"+name+".txt";
//cout<<filename<<'\n';
ot.open(filename.c_str(),ios::out);
//ot << "output test\n"<<'\n';
string sta="start fshowOutput\\shower.exe "+name;
system(sta.c_str());
}
fshow::~fshow()
{
ot.close();
//cout<<name<<endl<<FindWindow(NULL,name.c_str())<<'\n';
if (autoClose)
// 可能的漏洞:
// 若构造函数与析构函数间隔时间太短,则会因为窗口没来得及打开而关闭失败
SendMessage(FindWindow(NULL,(wchar_t*)name.c_str()),WM_CLOSE,0,0);
//EndTask(FindWindow(NULL, (wchar_t*)name.c_str()));
if(/*autoClose&&*/autoDel){
string del="del /f fshowOutput\\"+name+".txt";
system(del.c_str());
}
}
void fshow::clean()
{
ot.seekp(0);
return;
}
shower.cpp
#include<iostream>
#include<fstream>
#include<windows.h>
#include<string>
using namespace std;
int main(int argc, char *argv[])
{
string setTi="title ";
setTi+=argv[1];
system(setTi.c_str());
string s="fshowOutput\\";
s+=argv[1];// argv[0]是程序名,argv[1]才是另外传入的第一个参数
s+=".txt";
// cout<<s<<endl;
// system("pause");
ifstream in;
in.open(s.c_str(),ios::in);
while(1){
in.seekg(0);
cout<<in.rdbuf();
Sleep(50);
system("cls");
}
in.close();
return 0;
}