C++ Reading file backwards from the end of the file

tp77 picture tp77 · Apr 4, 2013 · Viewed 15.2k times · Source

I am trying to write a program with a menu that reads from a text file a few different ways. I'm just working on menu option #2 still (reading backwards from the end of the file), but I can't wrap my head around what I'm doing wrong. I've been at this for a few days now and just can't find any good resources to help on this. Any help would be appreciated.

#include <iostream>
#include <string>
#include <iomanip>
#include <istream>
#include <math.h>
#include <fstream>

using namespace std;

const int SIZE = 20;                     
typedef char String[SIZE];

//prototypes
void Menu(int &);
void ReadFile(ifstream &);
void BackwardFile(ifstream &,long &);
long CountFile(ifstream &,long &);

int main()
{  
    char filename[]= "grades.txt";
    int choice;
    long numBytes;

    ifstream InList;
    InList.open(filename);

    if(InList.good())
    {
        do
        {         
            Menu(choice); 
            switch(choice)
            {
                case 1:  
                    ReadFile(InList);
                    break;
                case 2:
                    CountFile(InList,numBytes);
                    BackwardFile(InList,numBytes);
                    break;
                case 3:
                    cout << "Pick a start position between 0 - " << numBytes << endl;
                    break;
                /*case 4:*/

                case 5:
                    cout << "\n GOOD BYE." << endl << endl; 
                    break;
            }

        }while (choice != 5);                         
    }
    else
        cout << "File did not open successfully." << endl << endl;

    system("PAUSE");
    return EXIT_SUCCESS;
}

void Menu(int &choice) 
{ 
    cout << "\n    Choose an option:";
    cout << "\n...................................";
    cout << "\n 1- Display All Contents of the File";
    cout << "\n 2- Display Content in Reverse Order";
    cout << "\n 3- Display from Point A to Point B";
    cout << "\n 4- Display from Point B to Point A";
    cout << "\n 5- Exit";
    cout << "\n\n Enter your choice: ";
    cin >> choice; 
} 

void ReadFile(ifstream& inFile)
{
    char byte;

    inFile.clear();

    cout<< "\nReading contents from the file:" <<endl;
    if(inFile)
    {
        inFile.get(byte);
        while(inFile.good())
        {
            cout << byte;
            inFile.get(byte);  
        }
    }
    inFile.close();
}

void BackwardFile(ifstream& inFile, long& numBytes)
{
    char byte;

    inFile.clear();
    cout<< "\nReading contents backwards from the file:" <<endl;

    inFile.seekg(numBytes, ios::end);

    while(inFile)
    {
        inFile.get(byte);               
        cout << byte;
        numBytes--;
        inFile.seekg(numBytes);  
    }
    inFile.close();
}                              

long CountFile(ifstream& inFile, long& numBytes)                           
{
    inFile.seekg(0L, ios::end);
    numBytes = inFile.tellg();
    return numBytes;
}

Answer

Edison Chang picture Edison Chang · Jan 3, 2015

The following is my solution to the question. When open the file, I use ios::ate to set the file position to the end of the file and use seekg method to read back. I am not sure whether there is a more efficient way to solve this question.

void readFile(char *fileName){
    char c;
    std::ifstream myFile(fileName,std::ios::ate);
    std::streampos size = myFile.tellg();
    for(int i=1;i<=size;i++){
        myFile.seekg(-i,std::ios::end);
        myFile.get(c);
        printf("%c\n",c);
    }
}