I need to read numbers which are listed in a file from bottom up. How can I do that using C?
The file is like:
4.32
5.32
1.234
0.123
9.3
6.56
8.77
For example, I want to read the last three numbers. They have to be float
type.
8.77
6.56
9.3
PS.: Actually I need a solution which is playing with the file pointer position using fseek, etc.
It's important to understand that no modern operating system tracks the position of line breaks within a file. (VMS could, and I'm pretty sure so could some IBM mainframe operating systems, but you're probably not using any of those.) So it's not possible to seek to a line boundary. It is also not possible to read byte-by-byte in reverse order.
Therefore, the simplest way to read the last three numbers in the file, in reverse, is to read the entire file in forward order, keeping the most recently seen three numbers in a buffer. When you hit EOF, just process that buffer backward.
A more efficient, but significantly more complicated, technique is to guess a position close to but before the last three numbers in the file; seek to that position, then discard characters till you hit a line break; and use the technique in the previous paragraph from that point. If you guessed wrong and the buffer winds up with fewer than three numbers in it, guess again.
And a third approach would be to use fseek
(with SEEK_END
) and fread
to read the last 1024 or so bytes of the file, set a pointer to the end of the block, and parse it backward. This would be quite efficient, but would have even more headache-inducing corner cases to get right than the previous suggestion. (What exactly do you do if the last three lines of the file, collectively, are more than 1024 bytes long?)
FYI, the correct way to read floating-point numbers in C is to use fgets
and strtod
. DO NOT use either atof
or scanf
for this; atof
doesn't tell you about syntax errors, and scanf
triggers undefined behavior on overflow.
P.S. If you have the shell utility tac
(which is a GNUism), the easiest option of all would be to write your program to process the first three numbers on standard input, and then invoke it as tac < input.file | ./a.out
. Skimming the code leads me to believe that tac
implements my "third approach", with some additional cleverness.
Well, the obvious way is to read them all, put them into an array and then get the last three.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With