I am calling these functions:
unsigned blah[5];
lseek(0, 100, SEEK_CUR);
read(0, blah, sizeof(blah));
and
FILE *fr;
fr = fopen(arg[1], "r");
unsigned blah[5];
fseek(fr, 100, SEEK_CUR);
fread(blah, 1, sizeof(blah), fr);
And I run the first code my running this command:
cat TEXTFILE | ./a.out
I run the second code my running this command:
./a.out TEXTFILE
However, I am getting different results. While the first one seeked properly, so it reads the correct text, the second one is not. I want to use the second format, so what did I do wrong?
With the addition of an open(filename,O_RDONLY);
call to the first example, both worked fine for me. I suspect your problem is because of the call lseek(0, 100, SEEK_CUR);
, which is asking for a seek on standard input. You cannot always seek on standard in - if you have:
cat file | ./my_program
Then standard input is a fifo, and you can't seek. If I do this on my system, seek fails by returning -1
, with an error of "Illegal seek". This may be the problem you're having, and you might not notice since you don't check the return value of the seek call in your example.
Note that if you have:
./my_program < file
Then standard input is a file, and you may seek. On my system, seek returns 100
, and the output is correct.
Here is a program you can use to illustrate the return values:
int main(void){
int fd = 0;
char blah[5];
printf("Seek moved to this position: %d\n",lseek(fd, 100, SEEK_CUR));
perror("Seek said");
printf("Then read read %d bytes\n",read(fd, blah, sizeof(blah)));
printf("The bytes read were '%c%c%c%c%c'\n",blah[0],blah[1],blah[2],blah[3],blah[4]);
}
And here are two executions:
$ ./a.out < text
Seek moved to this position: 100
Seek said: Success
Then read read 5 bytes
The bytes read were '+++.-'
(Those are the correct bytes from position 100 in that file)
$ cat text | ./a.out
Seek moved to this position: -1
Seek said: Illegal seek
Then read read 5 bytes
The bytes read were '# def'
(Those bytes are the first 5 bytes of the file)
I also noticed that the standard input version was the one you said was working correctly. If you're having trouble with the FILE *
version, I suspect the fopen()
call is failing, so make sure you check the return value from fopen()
. Of course, you can always do this:
FILE *fr = stdin;
So that you're reading from standard in. However, as you can't always seek on standard in, I'd recommend always opening a file if you plan to seek.
Note that you can't seek on all devices that you can open files on (though you won't have a problem on most systems), so you should always check that the result of a seek()
to make sure it succeeded.
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