473,889 Members | 1,764 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

reading a file in reverse order (bootom-top)

Hello,

I have a question.

I try to print a ascii file in reverse order( bottom-top). Here is the logic.

1. Go to the botton of the file fseek(). move one character back to avoid the EOF.
2. From here read a character, print it, move the file pointer (FILE*) to 2 steps back (using fseek(fp, -2, SEEK_CUR)) to read the previous character.

This seems to be ok if the file has a single line (i.e. no new line character). The above logic fails if it encounters a new line character and gets into an infinite loop priting a series of new-line character.

To fix this I checked for the character read and if it is new-line character, I move the file pointer by 3 steps (fseek(fp, -3, SEEK_CUR)) and now the logic works fine.

Can anyone please explain me why a this special consideration for a new-line character.

Many Thanks in advance.

Thanks
Praveen
Nov 13 '05
20 33102
CBFalconer wrote:

Villy Kruse wrote:
CBFalconer <cb********@yah oo.com> wrote:
Mantorok Redgormor wrote:
>
... snip ...
>
> I think my version might outperform yours.
> fgets is kind of slow on large files.

I believe it doesn't do the same thing. In addition I doubt
that reading a file twice can be faster than reading it once.


Not to mention that reading the entire contents of a huge file
into memory is not exactly the best thing to do. But of course
having gigabytes of real memory available will surely help.


Inasmuch as my version also reads everything into memory, I didn't
consider that a valid objection :-) However the response to
memory allocation failure is also different.

Sorry I'm late. Here's mine. It reads the file twice but only one line
at a time is ever in memory.

#include <stdio.h>
#include <stdlib.h>

#define MAX(a,b) ((a) > (b) ? (a) : (b))

int main(int argc, char *argv[]) {
FILE *in = stdin, *out = stdout;
int ch, i, lines = 0, len = 0, max = 0;
long *linpa;
char *buff;
if (argc > 1)
if ((in = fopen(argv[1], "r")) == NULL)
fprintf(stderr, "Can't open %s\n", argv[1]),
exit(EXIT_FAILU RE);

if (argc > 2)
if ((out = fopen(argv[2], "w")) == NULL)
fprintf(stderr, "Can't make %s\n", argv[2]),
exit(EXIT_FAILU RE);

while ((ch = fgetc(in)) != EOF) {
++len;
if (ch == '\n') {
++lines;
max = MAX(len, max);
len = 0;
}
}

fprintf(stderr, "There are %d lines in %s\n", lines, argv[1]);
fprintf(stderr, "The longest of which is %d characters\n", max);

rewind(in);
buff = malloc(max + 1);
linpa = malloc((lines + 1) * sizeof *linpa);
if (buff == NULL || linpa == NULL)
fprintf(stderr, "Can't allocate memory\n"), exit(EXIT_FAILU RE);
i = 0;
linpa[i] = 0;
while ((ch = fgetc(in)) != EOF)
if (ch == '\n')
linpa[++i] = ftell(in);

for (i = lines - 1; i >= 0; --i) {
fseek(in, linpa[i], SEEK_SET);
fgets(buff, max+1, in);
fputs(buff, out);
}
return EXIT_SUCCESS;
}

--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #11
Joe Wright wrote:

CBFalconer wrote:

Villy Kruse wrote:
CBFalconer <cb********@yah oo.com> wrote:
> Mantorok Redgormor wrote:
>>
>... snip ...
>>
>> I think my version might outperform yours.
>> fgets is kind of slow on large files.
>
> I believe it doesn't do the same thing. In addition I doubt
> that reading a file twice can be faster than reading it once.

Not to mention that reading the entire contents of a huge file
into memory is not exactly the best thing to do. But of course
having gigabytes of real memory available will surely help.


Inasmuch as my version also reads everything into memory, I didn't
consider that a valid objection :-) However the response to
memory allocation failure is also different.

Sorry I'm late. Here's mine. It reads the file twice but only one line
at a time is ever in memory.


It still doesn't do the same thing :-) (besides reading the file
twice). Note that my version reversed the file, not just the line
order. I.e. every byte was reversed in order.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 13 '05 #12
CBFalconer wrote:

Joe Wright wrote:

CBFalconer wrote:

Villy Kruse wrote:
> CBFalconer <cb********@yah oo.com> wrote:
> > Mantorok Redgormor wrote:
> >>
> >... snip ...
> >>
> >> I think my version might outperform yours.
> >> fgets is kind of slow on large files.
> >
> > I believe it doesn't do the same thing. In addition I doubt
> > that reading a file twice can be faster than reading it once.
>
> Not to mention that reading the entire contents of a huge file
> into memory is not exactly the best thing to do. But of course
> having gigabytes of real memory available will surely help.

Inasmuch as my version also reads everything into memory, I didn't
consider that a valid objection :-) However the response to
memory allocation failure is also different.

Sorry I'm late. Here's mine. It reads the file twice but only one line
at a time is ever in memory.


It still doesn't do the same thing :-) (besides reading the file
twice). Note that my version reversed the file, not just the line
order. I.e. every byte was reversed in order.

Boo. That's not so hard at all.

.....

for (i = lines - 1; i >= 0; --i) {
fseek(in, linpa[i], SEEK_SET);
fgets(buff, max+1, in);
rev(buff);
fputs(buff, out);
}
return EXIT_SUCCESS;
}

void rev(char *src) {
char *des = src;
int tmp;
while (*des) ++des;
while (--des > src) {
tmp = *des;
*des = *src;
*src++ = tmp;
}
}

And mine is shorter than yours. (That really sounds wierd. Sorry.) :=)
--
Joe Wright http://www.jw-wright.com
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #13
sahukar praveen wrote:
Hello,

I have a question.

I try to print a ascii file in reverse order( bottom-top). Here is the
logic.

1. Go to the botton of the file fseek(). move one character back to
avoid the EOF.
2. From here read a character, print it, move the file pointer (FILE*)
to 2 steps back (using fseek(fp, -2, SEEK_CUR)) to read the previous
character.

This seems to be ok if the file has a single line (i.e. no new line
character). The above logic fails if it encounters a new line character
and gets into an infinite loop priting a series of new-line character.

To fix this I checked for the character read and if it is new-line
character, I move the file pointer by 3 steps (fseek(fp, -3, SEEK_CUR))
and now the logic works fine.

Can anyone please explain me why a this special consideration for a
new-line character.

Many Thanks in advance.

Thanks
Praveen

Here's a code example ripped directry from my "C Primer Plus" book:
Listing 13.5 The reverse.c Program
--snip--
/* reverse.c -- displays a file in reverse order */
#include <stdio.h>
#include <stdlib.h>
#define CNTL_Z '\032' /* eof marker in DOS text files */
#define SLEN 50
int main(void)
{
char file[SLEN];
char ch;
FILE *fp;
long count, last;

puts("Enter the name of the file to be processed:");
gets(file);
if ((fp = fopen(file,"rb" )) == NULL)
{ /* read-only and binary modes */
printf("reverse can't open %s\n", file);
exit(1);
}
fseek(fp, 0L, SEEK_END); /* go to end of file */
last = ftell(fp);
for (count = 1L; count <= last; count++)
{
fseek(fp, -count, SEEK_END); /* go backward */
ch = getc(fp);
/* for DOS, works with UNIX */
if (ch != CNTL_Z && ch != '\r')
putchar(ch);
/* for Macintosh */
/* if (ch == '\r')
putchar('\n');
else
putchar(ch); */
}
putchar('\n');
fclose(fp);
return 0;
}
--snip--
This operates on the idea that your lines are no longer than 50 chars... but
that's easy to work around. This should give you the basic idea.

Jeff

Nov 13 '05 #14
Jeff Rodriguez wrote:
.... snip ... Here's a code example ripped directry from my "C Primer Plus" book:
Listing 13.5 The reverse.c Program
--snip--
/* reverse.c -- displays a file in reverse order */
#include <stdio.h>
#include <stdlib.h>
#define CNTL_Z '\032' /* eof marker in DOS text files */
#define SLEN 50
int main(void)
{
char file[SLEN];
char ch;
FILE *fp;
long count, last;

puts("Enter the name of the file to be processed:");
gets(file);

^^^^
Enough said. Don't buy that book. Burn it if you have it. Also
missing any fflush.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!

Nov 13 '05 #15
Jeff Rodriguez wrote:
Here's a code example ripped directry from my "C Primer Plus" book:
Listing 13.5 The reverse.c Program
<snip>

puts("Enter the name of the file to be processed:");
gets(file);
This is enough to condemn the book.
if ((fp = fopen(file,"rb" )) == NULL)
{ /* read-only and binary modes */
printf("reverse can't open %s\n", file);
exit(1);
}
fseek(fp, 0L, SEEK_END); /* go to end of file */


If the file is binary, SEEK_END is not guaranteed to work. The Standard
says: "A binary stream need not meaningfully support fseek calls with a
whence value of SEEK_END."

<snip>

--
Richard Heathfield : bi****@eton.pow ernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #16
CBFalconer wrote:
Jeff Rodriguez wrote:

puts("Enter the name of the file to be processed:");
gets(file); ^^^^
Enough said. Don't buy that book. Burn it if you have it.


Yes - MPEG optional but desirable.
Also missing any fflush.


Why would he need fflush here?

--
Richard Heathfield : bi****@eton.pow ernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #17
Richard Heathfield wrote:
CBFalconer wrote:
Jeff Rodriguez wrote:

puts("Enter the name of the file to be processed:");
gets(file);

^^^^
Enough said. Don't buy that book. Burn it if you have it.


Yes - MPEG optional but desirable.
Also missing any fflush.


Why would he need fflush here?


Woops. At least it will do no harm.

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 13 '05 #18
Richard Heathfield wrote:
Jeff Rodriguez wrote:

Here's a code example ripped directry from my "C Primer Plus" book:
Listing 13.5 The reverse.c Program

<snip>
puts("Enter the name of the file to be processed:");
gets(file);

This is enough to condemn the book.

if ((fp = fopen(file,"rb" )) == NULL)
{ /* read-only and binary modes */
printf("reverse can't open %s\n", file);
exit(1);
}
fseek(fp, 0L, SEEK_END); /* go to end of file */

If the file is binary, SEEK_END is not guaranteed to work. The Standard
says: "A binary stream need not meaningfully support fseek calls with a
whence value of SEEK_END."

<snip>

"This should give you the basic idea. "

This snippet came from a chapter in the book before memory management, like I
said.. the basic idea. Dump all over the book if you wish, just keep in mind
that snippet is very out context and the reason I posted it here is convey the
basic idea of how to do what the OP wanted.

Jeff

Nov 13 '05 #19
Jeff Rodriguez wrote:
Richard Heathfield wrote:
Jeff Rodriguez wrote:

Here's a code example ripped directry from my "C Primer Plus" book:
Listing 13.5 The reverse.c Program

<snip>
puts("Enter the name of the file to be processed:");
gets(file);

This is enough to condemn the book.

if ((fp = fopen(file,"rb" )) == NULL)
{ /* read-only and binary modes */
printf("reverse can't open %s\n", file);
exit(1);
}
fseek(fp, 0L, SEEK_END); /* go to end of file */

If the file is binary, SEEK_END is not guaranteed to work. The Standard
says: "A binary stream need not meaningfully support fseek calls with a
whence value of SEEK_END."

<snip>

"This should give you the basic idea. "


But it doesn't - or at least, it doesn't from the point of view of this
newsgroup.
This snippet came from a chapter in the book before memory management,
like I said.. the basic idea. Dump all over the book if you wish, just
keep in mind that snippet is very out context and the reason I posted it
here is convey the basic idea of how to do what the OP wanted.


It conveys a non-portable technique which might be appropriate in a
platform-specific newsgroup such as comp.os.msdos.p rogrammer, but not in a
newsgroup such as this one, where we don't allow ourselves the luxury of
code that depends on non-portable tricks.

--
Richard Heathfield : bi****@eton.pow ernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
13779
by: Erik Andersson | last post by:
Hi! I need to read a file (line-by-line) in reverse order, without reading the whole file into memory first. Is there an easy way of doing this? As in, is there a PHP function I could use? The solution has to be platform independent, so "popen("tac $filename")... wouldn't work.
3
2796
by: James Lee | last post by:
I am doing a simple query like col1, col2, date, col4 from table1. All four colums are of type blob. For date column, I store a string like this: Fri Feb 13 11:01:24 2004 I store records as they come in so the oldest record is at the top of the table. When I select and display, I want to display them in reverse order (newest record at the top) but I can't sort on date with strings like that.
8
7620
by: vijay | last post by:
Hello, As the subject suggests, I need to print the string in the reverse order. I made the following program: # include<stdio.h> struct llnode { char *info;
15
21568
by: Fabio Cannizzo | last post by:
Is it possible to do something similar to the STL iterators, i.e. to execute a foreach loop in reverse order? Thanks, Fabio
10
5407
by: aatish19 | last post by:
1: Write a program that asks the user to input an integer value and print it in a reverse order Sample Output Enter any number 65564 Reverse of 65564 is 46556 2: Write a program that takes a string as an input and print it in reverse order.(don't use bulit-in/library function). Sample Output Enter any string: i m Kashif
3
4082
by: thrill5 | last post by:
I have an xml document such as: <device> <element>first</element> <element>second</element> </device> I am using this as the source for an xslt transform that goes like <xsl:for-each select="/device/element> This is the <xsl:value-of select="."/> element.
2
8568
by: srp8982 | last post by:
hello, I need help (code) on following program ,its in c... 1)allow user to write file name in command line, read the file... 2) count characters, spaces and no. of lines in file given... 3)read upto first 10 lines, and print them in reverse order thanking you in advance
6
5344
by: aburningflame23 | last post by:
alright this is my problem.....please help i need to write a program that reads 10 integers from a file into an array and then prints out the numbers in reverse order. It also prints out the greatest number, smallest number, and the average
0
9969
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11203
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10794
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10896
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10443
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9612
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7151
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6029
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4251
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.