In writing a logfile program, I need a function to output the log entries between two dates. I use seekg()
and tellg()
to save the position of the first entry to output and last entry and then go back later to output the data in between. However, seekg()
when told to seek back to the beginning position goes to position -1 (can be seen when ran through a debugger), and no output is created. seekg() works fine when seeking in other parts of the program.
#include <fstream>
#include <time.h>
#include <string>
#include <sys/stat.h>
#include <iostream>
#include <stdbool.h>
#include <cstdlib>
struct tm tmbeg;
struct tm tmend;
struct tm tmlog;
time_t t;
int Y=0, m=0, d=0, H=0, M=0, S=0;
time_t formatdate(std::string date1)
{
struct tm sdate1={0,0,0,0,0,0,0,0,0};
char *p = NULL;
time_t t1=0;
p=(char *)strptime(date1.c_str(),"%Y-%m-%d %H:%M:%S",&sdate1);
if(p==NULL)
{
t1=0;
}
else
{
t1=mktime(&sdate1);
}
return t1;
}
bool time_to_start(time_t d1, time_t d2)
{
if(d1==d2) {return true;}
if(d2>d1) {return true;}
if(d2<d1) {return false;}
}
bool time_to_end(time_t d1, time_t d2)
{
if(d1==d2){return false;}
if(d1<d2) {return false;}
if(d2<d1) {return true;}
}
int main()
{
std::ifstream logfile;
logfile.open("log.txt", std::fstream::in);
std::string begdate, enddate, logdate, line;
begdate = "1995-08-11 13:23:15"; //actual program will have user-defined dates, but just define dates here to avoid entering them every time program is run
enddate = "2011-09-18 16:18:04";
time_t datestart = formatdate(begdate);
time_t dateend = formatdate(enddate);
time_t datetest;
std::ofstream::pos_type begin;
std::ofstream::pos_type end;
std::ofstream::pos_type current;
int ctrl = 0;
while(getline(logfile, line))
{
logdate = line.substr(0, 19);
datetest = formatdate(logdate);
if(ctrl == 1)
{
if(time_to_end(datetest,dateend))
{
logfile.seekg(current);
end = logfile.tellg(); //When to end
ctrl = 2;
}
else
{}
}
else if(ctrl == 0)
{
if(time_to_start(datestart, datetest))
{
logfile.seekg(current);
begin = logfile.tellg();
ctrl = 1;
}
}
else //if ctrl == 2
{
end = logfile.tellg();
break;
}
current = logfile.tellg();
}
logfile.seekg(begin);
current = logfile.tellg();//Here it can be seen that seekg(begin) had seeked to poition -1
unsigned length = end - begin < 100000 ? end - begin : 100000;
char* retBuf = new char[length];
logfile.read(retBuf, length);
if(retBuf)
{
std::string returnstr(retBuf);
std::cout << returnstr << std::endl;
}
else
std::cout << "nothing\n";
logfile.close();
delete[] retBuf;
return 0;
}
If anyone could figure out why it does not work there, that would be great.