Thread: Very Very Weird Situation

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    84

    Very Very Weird Situation

    Guys please check the following code.
    It prints a file backwards, but has very weird behavior.
    Whenever we reach to the beginning of the file,
    We go back to the end and print the file over and over again! I don't understand how this could be, fseek() not allow to go back from the beginning.

    I'm posting this code even that I've fixed the problem.
    I still want to understand how can it be.
    Code:
        fpRead=fopen("fileseek.c","rb");
    	if (fpRead==NULL)
    	{
    		puts("File not found!");
    		exit(1);
    	}
    
    	if (fseek(fpRead,-1L,SEEK_END))
    	{
    		puts("Error skipping file");
    		exit(1);
    	}
    
    
    	while ((fread(&cReadByte,sizeof(char),1,fpRead)) && (ftell(fpRead)>0))
    	{
    	
    		//printf("%ld\n",ftell(fpRead));
    	                putchar(cReadByte);
    		fseek(fpRead,-2,SEEK_CUR);
    		
    	}
    If ftell is enabled the output will be something like this:
    12
    11
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    12
    11
    10
    .
    .
    .

    Many thanks

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    When your code gets to the beginning of the file, it will call fread() to read one character. At that point ftell() will return 1, not zero, because you have read one character from the beginning. So change your second test to ftell(fpRead) > 1.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    84
    Quote Originally Posted by grumpy View Post
    When your code gets to the beginning of the file, it will call fread() to read one character. At that point ftell() will return 1, not zero, because you have read one character from the beginning. So change your second test to ftell(fpRead) > 1.
    Still....
    When the code reach to the beginning of the file and I call fread() then yes ftell() will return 1,
    But I am using -2 in fseek() so the desribale result after calling ftell() will be -1, but it's not it is going to the end of the file again and loop to the beginning over and over.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The result of using fseek() to move before the beginning of a file is an error. Apart from the fact that your code is not testing for such an error, there is also the added complication that not all operating systems (or, more accurately, the disk management schemes associated with those operating systems) can actually detect that error.

    In any event, a subsequent call of ftell() is not required to return -1 in such a circumstance: in practice, it is more likely to return either the value of the pointer before calling fseek() or it will return 0.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    84
    I would apprichiate it if someone will try to run the code.
    I agree with all the replys, but running the code show otherwise, that's why I've post it!

    Thanks again

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Running this code:

    Code:
    while (fread(&cReadByte, sizeof(char), 1, fpRead) && ftell(fpRead) > 0)
    {
       printf("%ld\n", ftell(fpRead));
       fseek(fpRead,-2,SEEK_CUR);
    }
    on SLES 10 (Linux), compiled with gcc, produces:

    Code:
    8
    7
    6
    5
    4
    3
    2
    1
    2
    1
    ...
    So I'm guessing the behavior of fseek, when seeking beyond the start of the file, is implementation-dependent.

  7. #7
    Registered User
    Join Date
    Nov 2007
    Posts
    73
    i have run the code on tc2.0 it works fine...
    the result is perfect.. no flaws...

    and by the way fseek doesn't seek before the beginning of the file.....

    which compiler do u use?????

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > i have run the code on tc2.0 it works fine...
    You mean it worked "as you expected", and the implementation-defined behaviour worked in your favour.

    That in no way means that every other implementation out there is going to do the same thing. Someone else's implementation-defined behaviour will see you "exit stage left" in no uncertain terms.

    If you're using the standard API calls within the limits described by the standard, then a question like "which compiler" is meaningless as they all should be doing the same thing. That's not to say that compilers and libraries don't have bugs (they do), but the chances of you stumbling on one in such well-used areas is slim.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Nov 2007
    Posts
    73
    Quote Originally Posted by Salem View Post
    > i have run the code on tc2.0 it works fine...
    You mean it worked "as you expected", and the implementation-defined behaviour worked in your favour.

    That in no way means that every other implementation out there is going to do the same thing. Someone else's implementation-defined behaviour will see you "exit stage left" in no uncertain terms.

    If you're using the standard API calls within the limits described by the standard, then a question like "which compiler" is meaningless as they all should be doing the same thing. That's not to say that compilers and libraries don't have bugs (they do), but the chances of you stumbling on one in such well-used areas is slim.
    so you mean to say no code is perfect... i asked him which compiler because he was getting something wierd apart from the standard definition of fseek(); so it might be the fault of his compiler... i ve tried out several cases out of the reach....
    so if you mean no code is perfect can you please do the favour of directing me how to test a code to prove it to be completely right?????

  10. #10
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    He's saying that you should be writing code as per the standards, implementation independant -- not for some specific implementation. It's the story of, "It works for me". While it may work for you, it certainly doesn't mean it'll work for everyone else.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > so if you mean no code is perfect can you please do the favour of directing me how
    > to test a code to prove it to be completely right?????
    You can't. Testing can only prove the presence of features, not the absence of bugs. If it were really possible, do you think you'd ever see a hot-fix, update or service pack?

    > i asked him which compiler because he was getting something wierd apart from the standard definition of fseek();
    It seemed to me that seeking before the start of a file was UB, at which point the whole program becomes UB, and comments like "it works as expected with the foo compiler" don't really add anything to the discussion. There's a regular stream of code on the forum which only just passes the "works for me" test.

    The whole point is that it should work for everyone. When you can do this it means:
    - you can write code and be confident of it working without memorising an impossible list of "this works on the foo compiler, but not the bar compiler".
    - you can give code to someone else, and not have to check which compiler they're using.
    - you can upgrade your compiler at will, and not have to learn a whole bunch of new compiler-specific rules.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    If you wanted to see if it conforms to some standard, then you would have to get a copy of that standard and compare it against it. Here are some links to some C standards:

    http://cboard.cprogramming.com/showthread.php?t=84349

    Pay special attention to "Annex J (informative) Portability issues".

  13. #13
    Registered User
    Join Date
    Nov 2007
    Posts
    73
    SALEM and ZACS7 ... thankyou for the advice... surely portability would be an issue...
    but can you guys see any problem with the code... if yes please suggest....

    and SALEM your avatar says bye bye to void main...
    well i read about the discussion but didnt get the point perfectly well...
    can you explain or direct me...
    awaiting your assistance...

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > but can you guys see any problem with the code... if yes please suggest....
    I thought that was what we were talking about.
    There is no in between, it is either portable or broken. The way to fix the original post would be to pay attention to ALL return results, and not just some of them.

    > and SALEM your avatar says bye bye to void main...
    And the FAQ explains why.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Salem View Post
    > and SALEM your avatar says bye bye to void main...
    And the FAQ explains why.
    No it doesn't really... it never mentions why void main is so bad, only that it shouldn't be used and is not standard.
    void main is undefined because the runtime library expects main to return a value but when you define it with void, you return nothing, so the runtime library gets junk instead of a real return value (or not, as some compilers, like VC actually returns 0 if main is defined as void). Thus, the behavior is undefined (the result is not the same on all compilers). This is a short version.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. weird things with my linked list of queue
    By -EquinoX- in forum C Programming
    Replies: 3
    Last Post: 11-22-2008, 11:23 PM
  2. weird
    By kiz in forum C Programming
    Replies: 8
    Last Post: 09-24-2007, 01:16 AM
  3. Weird Characters With GetDlgItemText
    By execute in forum Windows Programming
    Replies: 4
    Last Post: 05-04-2006, 04:53 PM
  4. very weird problem (pointers I think)
    By hannibar in forum C Programming
    Replies: 2
    Last Post: 10-11-2005, 06:45 AM
  5. Getting weird characters in Strings
    By steve8820 in forum C Programming
    Replies: 3
    Last Post: 09-18-2001, 02:49 AM