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.