Assuming that you want the first 1000 bytes and the last 1000 bytes of a file, and largely ignoring problems with files smaller than 2000 bytes (it works, but you might want a different result), you could use:
#include <stdio.h>
enum { NUM_BYTES = 1000 };
int main(int argc, char **argv)
{
for (int x = 1; x < argc; x++)
{
FILE *fp = fopen(argv[x], "r");
if (fp)
{
char buffer[NUM_BYTES];
int nbytes = fread(buffer, 1, NUM_BYTES, fp);
fwrite(buffer, 1, nbytes, stdout);
if (fseek(fp, -NUM_BYTES, SEEK_END) == 0)
{
nbytes = fread(buffer, 1, NUM_BYTES, fp);
fwrite(buffer, 1, nbytes, stdout);
}
fclose(fp);
}
else
{
fprintf(stderr, "%s: could not open file %s\n", argv[0], argv[x]);
}
}
}
This uses fread()
, fwrite()
and fseek()
as suggested in the comments.
It also takes care to close successfully opened files. It does not demand write permissions on the files since it only reads and does not write those files (using "r"
instead of "r+"
in the call to fopen()
).
If the file is smaller than 1000 bytes, the fseek()
will fail because it tries to seek to a negative offset. If that happens, don't bother to read or write another 1000 bytes.
I debated whether to use sizeof(buffer)
or NUM_BYTES
in the function calls. I decided that NUM_BYTES
was better, but the choice is not definitive — there are cogent arguments for using sizeof(buffer)
instead.
Note that buffer
becomes a local variable. There's no need to zero it; only the entries that are written on by fread()
will be written by fwrite()
, so there is no problem resolved by bzero()
. (There doubly wasn't any point in that when the variable was global; variables with static duration are default initialized to all bytes zero anyway.)
The error message is written to standard error.
The code doesn't check for zero bytes read; arguably, it should.
If the NUM_BYTES
becomes a parameter (e.g. you call your program fl19
and use fl19 -n 200 file1
to print the first and last 200 bytes of file1
), then you need to do some tidying up as well as command-line argument handling.