This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Reading Formatted Input Submitted by

View the code comments for a description, plus usage instructions.

Download Associated File: Retrieve.cpp (11,901 bytes)

    // Programmed by William O'Brien <kernel@brunnet.net>. Essentially what
    // I've programmed is a class that simplifies reading formatting input
    // from files. I've made a main generic Retrieve class, and two others
    // that are specializations for int and double. These should make this
    // file pretty applicable as is for development.

    // To use this you simply pass the file name, format string and pointer
    // to buffer to store the value. The type of the buffer is passed to the
    // class as a template parameter. For complete examples check the main
    // driver program. Hope this could be of some use.

    // Note: If you are going to use this I would definately recommend that
    // you seperate the declarations and specialization declarations in a
    // header file along with their respective definitions. I would have done
    // so but I wanted things to be simple.

    #include <cstdlib>
    #include <fstream>
    #include <iostream>
    #include <string>
    using namespace std;

    template <typename tArgumentType>
    class Retrieve {
    private:
    	ifstream ifInput;
    	tArgumentType *tExtraction;
    	string sSearchString;
    	string sCurrentFileName;
    public:
    	Retrieve(void);
    	Retrieve(const char *szFileName);
    	Retrieve(const string &sFileName);
    	Retrieve(const char *szFileName,
    		const char *szReadString,
    		tArgumentType *tAddress);
    	Retrieve(const string &sFileName,
    		const string &sReadString,
    		tArgumentType *tAddress);
    	~Retrieve(void);
    	void CloseFile(void);
    	void ClearState(void);
    	void OpenFile(const char *szFileName);
    	void OpenFile(const string &sFileName);
    	void Read(void);
    	void ReadSameFile(void);
    	void SearchString(const char *szReadString);
    	void SearchString(const string &sReadString);
    	void ExtractAddress(tArgumentType *tAddress);
    };

    template <typename tArgumentType>
    Retrieve<tArgumentType>::Retrieve(void)
    {}

    template <typename tArgumentType>
    Retrieve<tArgumentType>::Retrieve(const char *szFileName)
    : sCurrentFileName(szFileName)
    {
    	OpenFile(szFileName);
    }

    template <typename tArgumentType>
    Retrieve<tArgumentType>::Retrieve(const string &sFileName)
    : sCurrentFileName(sFileName)
    {
    	OpenFile(sFileName);
    }

    template <typename tArgumentType>
    Retrieve<tArgumentType>::Retrieve(const char *szFileName,
    								  const char *szReadString,
    								  tArgumentType *tAddress)
    : sCurrentFileName(szFileName)
    {
    	sSearchString = string(szReadString);
    	OpenFile(szFileName);
    	ExtractAddress(tAddress);
    }

    template <typename tArgumentType>
    Retrieve<tArgumentType>::Retrieve(const string &sFileName,
    								  const string &sReadString,
    								  tArgumentType *tAddress)
    : sCurrentFileName(sFileName)
    {
    	sSearchString = sReadString;
    	OpenFile(sFileName);
    	ExtractAddress(tAddress);
    }

    template <typename tArgumentType>
    Retrieve<tArgumentType>::~Retrieve(void)
    {
    	CloseFile();
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::CloseFile(void)
    {
    	ifInput.close();
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::ClearState(void)
    {
    	ifInput.clear();
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::OpenFile(const char *szFileName)
    {
    	sCurrentFileName = string(szFileName);
    	if (ifInput.is_open())
    	{
    		ifInput.close();
    	}
    	ifInput.open(szFileName);
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::OpenFile(const string &sFileName)
    {
    	sCurrentFileName = string(sFileName);
    	if (ifInput.is_open())
    	{
    		ifInput.close();
    	}
    	ifInput.open(sFileName.c_str());
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::ExtractAddress(tArgumentType *tAddress)
    {
    	tExtraction = tAddress;
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::Read(void)
    {
    	string sLineBuffer;
    	string sExtraction;
    	ClearState();
    	if (ifInput)
    	{
    		getline(ifInput, sLineBuffer);
    	}
    	string::size_type stPosition = sLineBuffer.find(sSearchString);
    	while (ifInput && stPosition == string::npos)
    	{
    		getline(ifInput, sLineBuffer);
    		stPosition = sLineBuffer.find(sSearchString);
    	}
    	if (ifInput && stPosition != string::npos)
    	{
    		stPosition += sSearchString.size();
    	}
    	sExtraction = sLineBuffer.substr(stPosition, string::npos);
    	*tExtraction = sExtraction;
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::ReadSameFile(void)
    {
    	CloseFile();
    	OpenFile(sCurrentFileName);
    	Read();
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::SearchString(const char *szReadString)
    {
    	sSearchString = string(szReadString);
    }

    template <typename tArgumentType>
    void Retrieve<tArgumentType>::SearchString(const string &sReadString)
    {
    	sSearchString = string(sReadString);
    }

    template <>
    class Retrieve<int> {
    private:
    	ifstream ifInput;
    	tArgumentType *tExtraction;
    	string sSearchString;
    	string sCurrentFileName;
    public:
    	Retrieve(void);
    	Retrieve(const char *szFileName);
    	Retrieve(const string &sFileName);
    	Retrieve(const char *szFileName,
    		const char *szReadString,
    		tArgumentType *tAddress);
    	Retrieve(const string &sFileName,
    		const string &sReadString,
    		tArgumentType *tAddress);
    	~Retrieve(void);
    	void CloseFile(void);
    	void ClearState(void);
    	void OpenFile(const char *szFileName);
    	void OpenFile(const string &sFileName);
    	void Read(void);
    	void ReadSameFile(void);
    	void SearchString(const char *szReadString);
    	void SearchString(const string &sReadString);
    	void ExtractAddress(tArgumentType *tAddress);
    };

    template <>
    Retrieve<int>::Retrieve(void)
    {}

    template <>
    Retrieve<int>::Retrieve(const char *szFileName)
    : sCurrentFileName(szFileName)
    {
    	OpenFile(szFileName);
    }

    template <>
    Retrieve<int>::Retrieve(const string &sFileName)
    : sCurrentFileName(sFileName)
    {
    	OpenFile(sFileName);
    }

    template <>
    Retrieve<int>::Retrieve(const char *szFileName,
    								  const char *szReadString,
    								  tArgumentType *tAddress)
    : sCurrentFileName(szFileName)
    {
    	sSearchString = string(szReadString);
    	OpenFile(szFileName);
    	ExtractAddress(tAddress);
    }

    template <>
    Retrieve<int>::Retrieve(const string &sFileName,
    								  const string &sReadString,
    								  tArgumentType *tAddress)
    : sCurrentFileName(sFileName)
    {
    	sSearchString = sReadString;
    	OpenFile(sFileName);
    	ExtractAddress(tAddress);
    }

    template <>
    Retrieve<int>::~Retrieve(void)
    {
    	CloseFile();
    }

    template <>
    void Retrieve<int>::CloseFile(void)
    {
    	ifInput.close();
    }

    template <>
    void Retrieve<int>::ClearState(void)
    {
    	ifInput.clear();
    }

    template <>
    void Retrieve<int>::OpenFile(const char *szFileName)
    {
    	sCurrentFileName = string(szFileName);
    	if (ifInput.is_open())
    	{
    		ifInput.close();
    	}
    	ifInput.open(szFileName);
    }

    template <>
    void Retrieve<int>::OpenFile(const string &sFileName)
    {
    	sCurrentFileName = string(sFileName);
    	if (ifInput.is_open())
    	{
    		ifInput.close();
    	}
    	ifInput.open(sFileName.c_str());
    }

    template <>
    void Retrieve<int>::ExtractAddress(tArgumentType *tAddress)
    {
    	tExtraction = tAddress;
    }

    template <>
    void Retrieve<int>::Read(void)
    {
    	string sLineBuffer;
    	string sExtraction;
    	ClearState();
    	if (ifInput)
    	{
    		getline(ifInput, sLineBuffer);
    	}
    	string::size_type stPosition = sLineBuffer.find(sSearchString);
    	while (ifInput && stPosition == string::npos)
    	{
    		getline(ifInput, sLineBuffer);
    		stPosition = sLineBuffer.find(sSearchString);
    	}
    	if (ifInput && stPosition != string::npos)
    	{
    		stPosition += sSearchString.size();
    	}
    	sExtraction = sLineBuffer.substr(stPosition, string::npos);
    	*tExtraction = atoi(sExtraction.c_str());
    }

    template <>
    void Retrieve<int>::ReadSameFile(void)
    {
    	CloseFile();
    	OpenFile(sCurrentFileName);
    	Read();
    }

    template <>
    void Retrieve<int>::SearchString(const char *szReadString)
    {
    	sSearchString = string(szReadString);
    }

    template <>
    void Retrieve<int>::SearchString(const string &sReadString)
    {
    	sSearchString = string(sReadString);
    }

    template <>
    class Retrieve<double> {
    private:
    	ifstream ifInput;
    	tArgumentType *tExtraction;
    	string sSearchString;
    	string sCurrentFileName;
    public:
    	Retrieve(void);
    	Retrieve(const char *szFileName);
    	Retrieve(const string &sFileName);
    	Retrieve(const char *szFileName,
    		const char *szReadString,
    		tArgumentType *tAddress);
    	Retrieve(const string &sFileName,
    		const string &sReadString,
    		tArgumentType *tAddress);
    	~Retrieve(void);
    	void CloseFile(void);
    	void ClearState(void);
    	void OpenFile(const char *szFileName);
    	void OpenFile(const string &sFileName);
    	void Read(void);
    	void ReadSameFile(void);
    	void SearchString(const char *szReadString);
    	void SearchString(const string &sReadString);
    	void ExtractAddress(tArgumentType *tAddress);
    };

    template <>
    Retrieve<double>::Retrieve(void)
    {}

    template <>
    Retrieve<double>::Retrieve(const char *szFileName)
    : sCurrentFileName(szFileName)
    {
    	OpenFile(szFileName);
    }

    template <>
    Retrieve<double>::Retrieve(const string &sFileName)
    : sCurrentFileName(sFileName)
    {
    	OpenFile(sFileName);
    }

    template <>
    Retrieve<double>::Retrieve(const char *szFileName,
    								  const char *szReadString,
    								  tArgumentType *tAddress)
    : sCurrentFileName(szFileName)
    {
    	sSearchString = string(szReadString);
    	OpenFile(szFileName);
    	ExtractAddress(tAddress);
    }

    template <>
    Retrieve<double>::Retrieve(const string &sFileName,
    								  const string &sReadString,
    								  tArgumentType *tAddress)
    : sCurrentFileName(sFileName)
    {
    	sSearchString = sReadString;
    	OpenFile(sFileName);
    	ExtractAddress(tAddress);
    }

    template <>
    Retrieve<double>::~Retrieve(void)
    {
    	CloseFile();
    }

    template <>
    void Retrieve<double>::CloseFile(void)
    {
    	ifInput.close();
    }

    template <>
    void Retrieve<double>::ClearState(void)
    {
    	ifInput.clear();
    }

    template <>
    void Retrieve<double>::OpenFile(const char *szFileName)
    {
    	sCurrentFileName = string(szFileName);
    	if (ifInput.is_open())
    	{
    		ifInput.close();
    	}
    	ifInput.open(szFileName);
    }

    template <>
    void Retrieve<double>::OpenFile(const string &sFileName)
    {
    	sCurrentFileName = string(sFileName);
    	if (ifInput.is_open())
    	{
    		ifInput.close();
    	}
    	ifInput.open(sFileName.c_str());
    }

    template <>
    void Retrieve<double>::ExtractAddress(tArgumentType *tAddress)
    {
    	tExtraction = tAddress;
    }

    template <>
    void Retrieve<double>::Read(void)
    {
    	string sLineBuffer;
    	string sExtraction;
    	ClearState();
    	if (ifInput)
    	{
    		getline(ifInput, sLineBuffer);
    	}
    	string::size_type stPosition = sLineBuffer.find(sSearchString);
    	while (ifInput && stPosition == string::npos)
    	{
    		getline(ifInput, sLineBuffer);
    		stPosition = sLineBuffer.find(sSearchString);
    	}
    	if (ifInput && stPosition != string::npos)
    	{
    		stPosition += sSearchString.size();
    	}
    	sExtraction = sLineBuffer.substr(stPosition, string::npos);
    	*tExtraction = atof(sExtraction.c_str());
    }

    template <>
    void Retrieve<double>::ReadSameFile(void)
    {
    	CloseFile();
    	OpenFile(sCurrentFileName);
    	Read();
    }

    template <>
    void Retrieve<double>::SearchString(const char *szReadString)
    {
    	sSearchString = string(szReadString);
    }

    template <>
    void Retrieve<double>::SearchString(const string &sReadString)
    {
    	sSearchString = string(sReadString);
    }

    // Data.dat contents:

    // Programmer: William O'Brien
    // Age: 17
    // Language: C, C++, STL
    // Dream: Game Programmer

    int main(void)
    {
    	string sProgrammerAge;
    	Retrieve<string> rAge("Data.dat", "Age: ", &sProgrammerAge);
    	rAge.Read();
    	cout << sProgrammerAge << endl;
    	rAge.SearchString("Programmer: ");
    	rAge.ReadSameFile();
    	cout << sProgrammerAge << endl;
    	rAge.CloseFile();
    	int iProgrammerAge;
    	Retrieve<int> rAgeAgain("Data.dat", "Age: ", &iProgrammerAge);
    	rAgeAgain.Read();
    	cout << iProgrammerAge << endl;
    	return 0;
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.