This is the code which put an extra line to the std::string array. I am here trying to print last k lines of file. Any help is appreciated.

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

//file.exceptions(ifstream::eofbit | ifstream::failbit | ifstream::badbit);
void print_last(unsigned k, string file_name)
{
    string *data=new string[k];
    unsigned last=0;
    ifstream is;
    is.open(file_name.c_str(), ios::binary);
    if(is.is_open())
    {
        while(getline(is, data[last]))  //while (getline( myfile, line ))  // same as: while (getline( myfile, line ).good())
        {
            last=(last+1)%k;
        }
        is.close();
        for(int i=0;i<k;i++)
        {
            last=(last+1)%k;
            cout<<data[last]<<endl;
        }
    }

}

int main()
{
    unsigned k;
    string file_name;
    cin>>k>>file_name;
    print_last(k, file_name);
}

Dani AI

Generated

The extra blank line is a bookkeeping issue, not a getline bug. The loop in the original code writes lines into a k‑slot circular buffer and then blindly prints k slots afterward. If the file contains fewer than k lines (or if the buffer contains an unused/empty slot), that unused slot shows up as the extra empty line. was right to point out blank lines in the file can be a factor; correctly moved to an intermediate string. The missing piece is counting how many successful reads actually happened and printing only those (or using a container that naturally keeps only the last k lines).

A simple, robust approach: collect lines and either

  • track the number of successful getline calls and compute a start index for the circular buffer, or
  • use a deque that drops the oldest line when size exceeds k (this avoids manual wrap arithmetic).

Example using std::deque (keeps semantics simple and readable):

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

std::deque<std::string> dq;
std::string line;
std::ifstream is(file_name);
if (is) {
    while (std::getline(is, line)) {
        if (dq.size() == k) dq.pop_front();
        dq.push_back(line);
    }
    for (const auto &s : dq) std::cout << s << '\n';
}

Additional notes: prefer RAII containers (std::vector/std::deque) over raw new/delete; avoid opening the file with ios::binary unless binary handling is intended; decide whether to treat empty/whitespace-only lines as meaningful (skip with if (line.empty()) continue; only when appropriate); the last file line without a trailing newline is still returned by getline. This explanation ties together the observations from , and and gives a simple, correct pattern to reliably print the last k human-readable lines.

Recommended Answers

All 7 Replies

Check your text file -- your program ran ok for me. I have a text file that lists US state names and their abbreviations. Ran your program with "5 states.txt" and it printed the last 5 lines of that file. If the text file contains blank lines at the beginning or end of the file your program may not produce the desired results unless you expect the blank lines.

What problem are you having such that you need help? Simply saying "Any help is appreciated" is very broad. For example, I'd do something completely different; does throwing away your code and starting over constitute "help"?

It seems strange but on my console it is showing only last four lines plus an extra empty line. Moreover, I have tested it with three files.

What problem are you having such that you need help?
It is actually storing an extra empty empty string to the data array but I intend to print last 5 human readable lines of a file.

It is actually storing an extra empty string in the data array but I intend to print last 5 human readable lines of a file.

You can change your program to ignore empty lines, just add the check just before line 17. If the line is empty don't increment the counter. But that may cause other undesireable side affects. Your program runs correctly as it is, if it doesn't display the lines you think it should then you need to edit the text file and remove the blank lines.

I was updating the std::string data array even at the end of file which was owverwriting the oldest line stored in k sized array. I have changed it to use an intermediate string instead and is working fine with this modification.

void print_last(unsigned k, string file_name)
{
    string *data=new string[k];
    string str;
    unsigned last=0;
    ifstream is;
    is.open(file_name.c_str(), ios::binary);
    if(is.is_open())
    {
        while(getline(is, str)) //while (getline( myfile, line ))  // same as: while (getline( myfile, line ).good())
        {
            data[last]=str;
            last=(last+1)%k;
        }
        is.close();
        for(int i=0;i<k;i++)
        {
            cout<<data[last]<<endl;
            last=(last+1)%k;
        }
    }
    delete[] data;

}
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.