I have a file that consists of dates like this:

12/01/2008
12/02/2008
12/03/2008
12/04/2008
12/05/2008

Now if I will read this file from beginning to end, this is a solution:

String^ FilePath = "C:\\DateFile.txt";
String^ GetLine = "";

StreamReader^ Read = gcnew StreamReader(FilePath);

while(Read->Peek() >= 0 )
{
      GetLine = Read->ReadLine();
      if( GetLine == "12/[B]04[/B]/2008" )
      {
             //Do something
      }  
}
Read->Close();

Now is my problem as follows. This file is very large, about 50 MB and consists of Dates in an ascending order.
As I have done a test that I will only want to start reading this file from the date "12/[B]04[/B]/2008" so reading this file from beginning to end is not effective.

How is it possible to start read this file from this date ? What could be an approach to this ?
"12/[B]04[/B]/2008"

Hi sfuo,

I dont think that will be the solution to the problem as it is needed to retreive the whole date: "12/04/2008".

The date always has this format through the file and dates comes in ascending order. Important is not to read the file from beginning to end. There must be a way to effectively search for the position to Start read from.

I am really searching for the fastest solution and also wonder if opening the file in binary mode can be a part of a possible solution.

Edited 7 Years Ago by Darth Vader: n/a

I am thinking of if the right way to search for the desired date in a file and start read the file from there is to do some type of algorithm where you "jump" in the file to different positions and see if the date if before or after that position.

I am not sure of wich approach that is correct ?

OK you will have to change lots of things for what you need but this searches a sorted file for a date using a binary search.

#include <fstream>
#include <iostream>
#include <string>

using namespace std;

bool greaterThan(string a, string b)
{
	//format mm/dd/yyyy
	int Ya = atoi(a.substr(6, 4).c_str());
	int Yb = atoi(b.substr(6, 4).c_str());
	
	int Ma = atoi(a.substr(0, 2).c_str());
	int Mb = atoi(b.substr(0, 2).c_str());
	
	int Da = atoi(a.substr(3, 2).c_str());
	int Db = atoi(b.substr(3, 2).c_str());
	
	if( Ya > Yb ) //compares years
		return true;
	else if( Ya < Yb )
		return false;
	
	if( Ma > Mb ) //compares months
		return true;
	else if( Ma < Mb )
		return false;
	
	if( Da > Db ) //compares days
		return true;
	else if( Da < Db )
		return false;
}

int main()
{
	bool found;
	int minP, midP, maxP;
	string minS, midS, maxS;
	string finding = "22/22/2222"; //date to find
	ifstream in;
	
	in.open("text.txt", ios::ate);
	
	//my text.txt was
	/*
	00/00/0000
	11/11/1111
	22/22/2222
	33/33/3333
	44/44/4444
	55/55/5555
	66/66/6666
	77/77/7777
	88/88/8888
	99/99/9999  //make sure that there is a newline at the end of the file
				//otherwise it does not work because it is not all 12 base
				//(10 date characters and 2 for newline character)
	*/
	
	in.seekg(-12, ios::end); //start of the last date
	maxP = in.tellg();
	in >> maxS;
		
	if( maxS == finding )
	{
		found = true;
		cout << "FOUND" << endl;
		cout << maxS << endl;
	}
	
	in.seekg(0, ios::beg); //start of the first date
	minP = in.tellg();
	in >> minS;
	if( minS == finding )
	{
		found = true;
		cout << "FOUND" << endl;
		cout << minS << endl;
	}
	
	while( !found )
	{
		midP = ((minP/12+maxP/12)/2)*12; //start of middle date
		in.seekg(midP, ios::beg);
		
		in >> midS;
		if( midS == finding )
		{
			found = true;
			cout << "FOUND" << endl;
			cout << midS << endl;
			break;
		}
		cout << minS << " " << midS << " " << maxS << endl;
		if( greaterThan(finding, midS))
		{
			minS = midS;
			minP = midP;
		}
		else
		{
			maxS = midS;
			maxP = midP;
		}
	}
	system("PAUSE");
	return 0;
}

This outputs "found" and the date it found.

You will need to add an input date and what you want it to do after it has found your date.

If you have any questions just ask.

This article has been dead for over six months. Start a new discussion instead.