Hi, i am trying to write a program that would work much like the tail command in UNIX. The idea is to print the last 10 lines of a file. I started off by finding out how many lines were in the file, then attempted to seek to the appropriate line number to as to print the last 10 lines, however i then realised seekg was seeking character by character, not by the lines. How can i seek to a specific line?
Here is my code

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

using namespace std;

int main()
{	int lineCount=0;
	fstream file;
	char filename[10];
	string line;

	cout << "Enter file name" << endl;
	cin >> filename;

	file.open(filename);
	if(file.good())
	{	
		cout << "file opened successfully" << endl;

		string t;
		

		while(getline(file, t, '\n'))
		
		++lineCount;
	
		

	}
	else
	{
		cout << "Error file does not exist" << endl;
	}
	file.close();

	file.open(filename);
	if(file.good())
	{	
		int x = lineCount - 10;

		file.seekp (x, ios::beg);
		
		getline (file, line);
		cout << line << endl;
		while(! file.eof() )
   		{
			
			getline (file,line);
      			cout << line << endl;
		}
	}
	file.close();
		
	return 0;
}

Recommended Answers

All 6 Replies

you need a vector<unsigned int> that contain the offsets for each line. Create that array during the loop on line 24. For each line call tellg() to get the offset. Then you can use that info on line 42.

im not to sure if i understand what your saying. I need to create an array of unsigned int? Then store the offset of each line into the array? Then use those values to seek to the desired line??

here is my code, i know it is not what you ask, but i have fun to wright it.

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

void read_lines(fstream& file, int& line, string& last_lines){
	string t;
	if (getline(file, t, '\n')){
		read_lines(file, line, last_lines);
	}
	if (line >= 0){
		t+='\n';
		--line;
		last_lines = t + last_lines ;
	}
	else{
		return;
	}
}

int main()
{
	fstream file;
	string filename;

	cout << "Enter file name" << endl;
	getline(cin, filename);

	file.open(filename.c_str());
	if (file.good())
	{
		cout << "file opened successfully" << endl;
		string last_lines = "";
		int lines = 10;
		read_lines(file, lines, last_lines);
		cout << last_lines;
	}
	else
	{
		cout << "Error file does not exist" << endl;
		return 1;
	}
	file.close();

	return 0;
}

that works great! I will try implement a similar method into my own code, thanx for the help :)

im not to sure if i understand what your saying. I need to create an array of unsigned int? Then store the offset of each line into the array? Then use those values to seek to the desired line??

I guess you have never worked with arrays before?? Note: ivailosp had a better idea.

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

int main()
{
    int lineCount=0;
    fstream file;
    char filename[10];
    string line;
    vector<size_t> offsets; 
    cout << "Enter file name" << endl;
    cin >> filename;

    file.open(filename);
    if(file.good())
    {	
        cout << "file opened successfully" << endl;
        string t;
        while(getline(file, t, '\n'))
        {
            ++lineCount;
            size_t cnt = file.tellg();
            offsets.push_back(cnt);
        }
    }
    else
    {
        cout << "Error file does not exist" << endl;
    }
    file.clear(); // clear eof error flag 
    if(file.good())
    {	
        int x = lineCount - 10;

       file.seekp (offsets[x], ios::beg);
		
        while(getline (file, line))
        {
            cout << line << endl;
        }
    }
    file.close();
		
    return 0;
}

I have used arrays before, but never vectors. Thanx for your help also, both methods seem to work great. I will have to read up on vectors, they look useful.

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.