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.

Never mind, I figured it out. logfile.clear() needs to be added before line 94 to clear the file position.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.