This is for a project for everyone's awareness. It's my first project in C and have a question regarding lseek()
and moving the file pointer.
Right now I'm able to read the bitmap and DIB header of a bitmap file. I need to now traverse the pixels and manipulate them in certain ways. I have written out in pseudocode how I plan to tackle the manipulation. But I am having difficulty understanding how to properly use lseek
, as I keep getting incompatible pointer to integer conversion...
warnings with my code. I'll give a short example of my main method since this is for a project:
int main(int argc, const char * argv[]) {
FILE *fp;
if((fp = fopen(argv[1], "r+b")) == NULL){
printf("Error: Unable to open file.\n");
exit(0);
}
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
rewind(fp);
char test; // simply to test overwriting the current byte
fread(&test, sizeof(char), 1, fp);
test = ~test;
lseek(fp, -1, SEEK_CUR); //produces error
//also tried fseek prior to realizing I should be using lseek to move my pointer.
fwrite(&test, 1, sizeof(char), fp);
fclose(fp);
return 0;
}
Again, not trying to provide too much of my code since this is a project. But I'd like help understanding how to properly use lseek
please. I noticed that it returns an int
value, so I know that it is because my file pointer is of type FILE
. But what is the proper way to use this method? I saw one example that had opened the same file in both read and write mode, where write mode was using lseek
. But for some reason I don't know if that is correct or not.
EDITED Based on two members response, I changed my code above to:
rewind(fp);
lseek(fileno(fp), hdr.offset, SEEK_CUR); //hdr.offset == 54 bytes
printf("FD FILENO: %d\n", fileno(fp)); // prints 3???
printf("CURRENT POS: %p\n", fp); //prints 0x7fffe7eae0b0 (I understand it's an address)
fread(&test, sizeof(char), 1, fp);
lseek(fileno(fp), -1, SEEK_CUR);
fwrite(&test, 1, sizeof(char), fp);
printf("CURRENT POS: %p\n", fp); //prints the same address as above?
What am I not getting other than everything to do with C?
If you'd like to keep using FILE *fp
, which is probably a good idea, you can get convert fp
to its corresponding int
file descriptor with int fileno(FILE *stream)
. In other words,
lseek(fileno(fp), -1, SEEK_CUR);
Added
All works fine with fseek
.
#include <stdio.h>
int main(int argc, const char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
return 1;
}
FILE *fp;
if((fp = fopen(argv[1], "r+b")) == NULL){
fprintf(stderr, "Error: Unable to open fle '%s'.\n", argv[1]);
return 1;
}
char buf[17];
size_t n_read = fread(buf, sizeof(char), sizeof buf - 1, fp);
buf[n_read] = '\0';
printf("Initial contents: %s\n", buf);
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
printf("Position at end of file: %ld\n", fsize);
// Read first character in file.
rewind(fp);
char test;
fread(&test, sizeof(char), 1, fp);
++test;
fseek(fp, -1, SEEK_CUR);
fwrite(&test, sizeof(char), 1, fp);
rewind(fp);
n_read = fread(buf, sizeof(char), sizeof buf - 1, fp);
buf[n_read] = '\0';
printf("Final contents: %s\n", buf);
fclose(fp);
return 0;
}
And then
$ gcc foo.c -o foo
$ ./foo foo.c
Initial contents: #include <stdio.
Position at end of file: 881
Final contents: $include <stdio.