PapaSmurf
PapaSmurf

Reputation: 163

Reading in lines from a text file in reverse order c++

I need to find a way of reading in the last 6 lines of data from a file.

For example if I have 1 2 3 4 5 6 7 8 9 10

I need to read be able to get 10, 9, 8, 7, 6, 5, 4.

These need to then be put into variables or strings to be outputted later. Currently I have managed to read in the last line of the file but I have no idea how to then read in the other 5 numbers.

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

using namespace std; 

int main()
{
    std::ifstream in("test.txt");

    if (in.is_open())
    {
        std::vector<std::string> lines_in_reverse;

        std::string line, line2;

        while (std::getline(in, line))
        {
            // Store the lines in reverse order.
            lines_in_reverse.insert(lines_in_reverse.begin(), line);



        }
        cout << line << endl;
        while (std::getline(in, line2))
        {
            // Store the lines in reverse order.
            lines_in_reverse.insert(lines_in_reverse.begin(), line2);



        }
        cout << line2 << endl;
    }

    cin.get();
    return 0;
}

Can anyone advise a way to this? I do not know of any functions or methods that can help.

EDIT

This method outputs the last 6 numbers from the file however they are backwards and I need a way to reverse them and get rid of the whitespace it prints out.

I'm unsure on how to use reverse and which arguments are required from this - http://en.cppreference.com/w/cpp/algorithm/reverse

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    char x;
    ifstream f("test.txt", ios::ate);
    streampos size = f.tellg();
    for (int var = 1; var <= size; var++){
        f.seekg(-var, ios::end);
        f.get(x);
        reverse(x);
        cout << x; 
    }
    cin.get();
    return 0;
}

Alot of the responses show me how to reverse the text file using vectors but not the last 6 numbers which is the only information I need.

Regards

Upvotes: 0

Views: 8693

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409442

How to read a file and print it reverse, in only three statements of code (excluding declarations and other boilerplate):

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

void read_and_print_reverse_n(std::istream& is, const int n)
{
    std::vector<std::string> v;

    // This call reads all whitespace-delimited "words" from the input stream
    // and appends them to the vector
    std::copy(std::istream_iterator<std::string>(is),
              std::istream_iterator<std::string>(),
              std::back_inserter(v));

    // Output the last `n` lines from the input
    for (const auto i = v.rbegin();
         i < v.rend() && i < v.rbegin() + n;
         ++i)
    {
        std::cout << *i << '\n';
    }
}

int main()
{
    read_and_print_reverse_n(std::cin, 6);
}

References

Upvotes: 2

richik jaiswal
richik jaiswal

Reputation: 2102

I think the answer here would solve the purpose where you store the lines in a vector and iterate the vector from the end.

As you are looking for some direct method to read the file, you can read the file character by character starting from the end using seekg and tellg.

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    using namespace std;
    int main()
    {
        char x;
        ifstream f("filename.txt",ios::ate);
        streampos size = f.tellg();
        for(int var=1;var<=size;var++){
            f.seekg(-var,ios::end);
            f.get(x);
            printf("%c",x);
        }
        return 0;
    }

You can also keep a count of \n to keep a track of the number of lines read from the end.

Upvotes: 1

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145429

It's not a good idea to store all the lines you read in, because there can be e.g. a billion lines.

You only need to store the last 6.

The following code is designed to produce those lines in reverse order, as the question indicates that is a requirement:

#include <iostream>
#include <string>
#include <deque>
using namespace std;

auto main() -> int
{
    string          line;
    deque<string>   last_lines;
    while( getline( cin, line ) )
    {
        if( last_lines.size() == 6 )
        {
            last_lines.pop_back();
        }
        last_lines.push_front( line );
    }

    for( auto const& s : last_lines )
    {
        cout << s << endl;
    }
}

The output here is not exactly the question's example

10, 9, 8, 7, 6, 5, 4

because that's 7 lines, contradicting the 6 that's stated in the first sentence.

Upvotes: 2

Related Questions