Search code examples
cfseek

FSEEK gets the position of the last character instead of the wanted one


I am making a program that enables the user to edit a text file. One of the available options is "move". When selected, the program asks for a number of character to skip, and it skips them in the file, using fseek.

However to do that I need to ensure that the position the user tries to reach corresponds to an actual character. To do so, I have created a function that checks if the skipping is possible.

This is how I do:

  1. I save the position in the file, as pos.
  2. I use fseek to get the position of the last character in the file.
  3. I compare this position to the position corresponding to the sum of pos and the number of characters that the user wants to skip.
  4. Whether the result is true or false, the position in the file is always reset to its initial value, pos, using fseek.

This is my original code:

if (pos + nb > ftell(file))
{
    fseek(file, 0, pos);
    return (1);
}
else
{
    fseek(file, 0, pos);
    return (0);
}

With this code, if the initial value, pos, is not 0, fseek will not reset the position to pos, but to the position of the last character. (?!) I found out that replacing the order of the arguments and passing pos as the offset and 0 as the starting position makes it work. But I can't get why the previous code doesn't work.

I would like some help to understand better how the function fseek works, there are, obviously, some details that I fail to find. I found nothing about "fseek" in the GNU C reference manual...


Solution

  • You are using fseek() wrong, try

    fseek(file, pos, SEEK_SET);
    

    always read the (documentation or specification), it will save you a lot of problems.

    I found out that replacing the order of the arguments and passing pos as the offset and 0 as the starting position makes it work. But I can't get why the previous code doesn't work

    Well, it's because that's the right order for the parameters, and incidentally 0 is the value of SEEK_SET.

    Also, you need to be careful, you say number of characters and that is not the same as number of bytes, for instance in UTF-8 number of bytes for character encoding varies from one character to another. According to the fseek() specification, it skips pos bytes, not characters.