From: Glynn Clements <glynn@gclements.plus.com>
To: Venkatesh Joshi <joshiv@cisco.com>
Cc: LinuxC <linux-c-programming@vger.kernel.org>
Subject: Re: how to implement tail -n
Date: Mon, 24 Jan 2005 19:26:52 +0000 [thread overview]
Message-ID: <16885.19452.391228.523655@gargle.gargle.HOWL> (raw)
In-Reply-To: <009a01c501d8$6d504cf0$dc846840@apac.cisco.com>
Venkatesh Joshi wrote:
> I would like to know how to implement "tail -n" in C.
Use a circular buffer which contains the last N lines read. Each time
you read a line, remove the first line and add the new line to the end
of the buffer. When you reach the end, display the contents of the
buffer.
E.g.
void tail(FILE *fp, int num_lines)
{
char **buffer = calloc(num_lines, sizeof(char *));
int index = 0;
int i;
for (;;)
{
char *line = NULL;
int len = 0;
if (getline(&line, &len, fp) < 0)
break;
if (buffer[index])
free(buffer[index]);
buffer[index] = line;
index++;
index %= num_lines;
}
for (i = 0; i < num_lines; i++)
puts(buffer[(index + i) % num_lines]);
}
In practice, you would probably want to do your own memory allocation
rather than using getline(). You also need to allow for files with
less than num_lines lines..
> The "-n" option will be used to print the last n lines of a file -
> rather than the default option of printing the last 10 lines of a file.
>
> I wish to do this in a single pass. I can use lseek() to go to the end
> of the file. How to traverse backwards from there ? Is there any
> function that does this ?
Use lseek(SEEK_CUR) with a negative offset to seek backwards. You
would have to use trial and error to determine how much you need to
read.
Also, lseek() will only work on regular files. It won't work on pipes,
etc. The "tail" command works on pipes.
--
Glynn Clements <glynn@gclements.plus.com>
prev parent reply other threads:[~2005-01-24 19:26 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-23 6:26 pointer initialization of string constant Krishna Mohan
2005-01-23 12:45 ` Progga
2005-01-23 13:36 ` Krishna Mohan
2005-01-24 5:49 ` how to implement tail -n Venkatesh Joshi
2005-01-24 6:30 ` Eric Bambach
2005-01-25 14:10 ` Robert Lorentz
2005-01-24 19:26 ` Glynn Clements [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16885.19452.391228.523655@gargle.gargle.HOWL \
--to=glynn@gclements.plus.com \
--cc=joshiv@cisco.com \
--cc=linux-c-programming@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).