Thread: EOF appears not on end of file?!

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    7

    EOF appears not on end of file?!

    Ive wrote a very simple pogram that encrypts a .txt file by reading every char in it , promoting it by 1, and then putting the result in a new .txt file .
    then the prog reads the "encrypted "file and decrypts it by substructing 1 from every char.

    for example if those chars apear in the file :
    Code:
    abcd123
    after running the program it creats 2 files :
    encrypted.txt:
    Code:
    bcde234
    and decrypted.txt
    Code:
    abcd123

    BUT when i run the program on a file with those chars:
    Code:
    Edֳ$x7ֳ$x7ֳ$x7987ֶ$x7d7ָ$x7ֳ$x7ֲ$x7ֳ$y7D$x79a7־$x7T=7ֲ$x7e7$x79E7ֲ$x7Richֳ$x7                        PE  L };        א   (  
    the result is :
    encrypted.txt:
    Code:
    Feִ%y8ִ%y8ִ%y8:98ַ%y8e8ֹ%y8ִ%y8ֳ%y8ִ%z8E%y8:b8ֿ%y8U>8ֳ%y8f8א%y8:F8ֳ%y8Sjdiִ%y8!!!!!!!!!!!!!!!!!!!!!!!!QF!!M!~<!!!!!!!!ב!!!)!!!
    decrypted.txt:
    Code:
    Edֳ$x7ֳ$x7ֳ$x7987ֶ$x7
    this is the code:

    Code:
    while(ch!=EOF){ /*encryption*/
                                         ch=fgetc(src); /* ch,chr are int  */
                                         chr=ch+1;
                                         fputc(chr,dst);
                   }
    Code:
    while(ch2!=EOF){ /*decryption*/
                                         ch2=fgetc(src); /*  ch2,chr2 are int   */
                                         chr2=ch2 -1;
                                         fputc(chr2,dst);
                   }
    I think the problem is that for some reason when the chars " "appear the compiler thinks one of them is an EOF and stops.

    can that be the problem or is it something else?
    plz hlp me fix this BUG!

  2. #2
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    I think you might want something like this:
    Code:
    while (EOF != (ch2 = fgetc(src))) {
       chr2 = ch2 - 1;
       fputc (chr2, dst);
    }
    Otherwise you're putting the decrement of character into the resulting file and then checking it for NULL. Whether this solves your problem, I don't know :-P

  3. #3
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You should also limit the encrypted characters to "printable" characters. See isprint() from ctype.h - to make sure you don't get any control characters in there... For example, NUL.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,176
    Lemme guess, you declared your 'ch' and 'ch2' as chars, rather than ints (which is what they should be declared as).

    If one of your encrypted characters equates to (char)EOF, there is no way for you to tell the difference between (char)EOF and a real end of file.
    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.

  5. #5
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Code:
    ch2=fgetc(src); /*  ch2,chr2 are int   */
    apparently they are declared as ints... ;-)

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    7

    ok,

    Quote Originally Posted by zacs7 View Post
    You should also limit the encrypted characters to "printable" characters. See isprint() from ctype.h - to make sure you don't get any control characters in there... For example, NUL.
    I changed the code so now the promotion and substrucion of chars is done only if the char is printble. ( using isprint() )

    that solved many problems including the bug in my first post.
    but, still i can find bugs like this:

    Code:
    source:   ־wֵ=־w׃=־w$@־wx־w־w@־w@ֿwL־w9ׁwq־wזדׂw..מ׀w    ״wץwש׳wזַw־<
    Code:
    encrypted ־xֵ>־x׃>־x%A־xy־x־xA־xAֿxM־x:ׁxr־xזדׂx..מ׀x!!!!״
    Code:
    decrypted ־wֵ=־w׃=־w$@־wx־w־w@־w@ֿwL־w9ׁwq־wזדׂw..מ׀w    ״
    again the programs stops after the '' char which is strange because as you can see in the example, sometimes when '' appears nothing happens, and sometimes when it appears the prog stops .
    any idea why is that ? and how to fix it ?
    thanks

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,176
    Posting your whole program would really help.
    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.

  8. #8
    Registered User
    Join Date
    Aug 2007
    Posts
    7
    Quote Originally Posted by Salem View Post
    Posting your whole program would really help.
    no problem
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include <ctype.h>
    int main()
    {
     FILE *dst ,*src;
     int ch,ch2;
    
    /**********opppening files**************/
    
     src=fopen("a.txt" ,"rt");
     if(src==NULL){
                   puts("error");
                   getchar();
                   exit(1);
                   }
     dst=fopen("Encrypted.txt" ,"wt");
     if(src==NULL){
                   puts("error");
                   getchar();
                   exit(1);
                   }
    /************encryption******************/
    while (EOF != (ch = fgetc(src))) 
          if(isprint(ch))
             fputc(ch +1, dst);
                                        
          else
            putc(ch, dst);
            
     fclose(dst);
     fclose(src);
     puts("done");
     getchar();
    /***************************************/
    
    
    /************opppening files*************/
    
     src=fopen("Encrypted.txt" ,"rt");
     if(src==NULL){
                   puts("error");
                   getchar();
                   exit(1);
                   }
     dst=fopen("Decrypted.txt" ,"wt");
     if(src==NULL){
                   puts("error");
                   getchar();
                   exit(1);
                   }
    /**************************************/
    
    /*************decryption****************/
    while (EOF != (ch2 = fgetc(src))) 
          if(isprint(ch2))
             fputc(ch2 -1, dst);
          else
             fputc(ch2, dst);
    
     fclose(dst);
     fclose(src);
     puts("done");
     getchar();
    /*************************************/
    }

  9. #9
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by v01d View Post
    no problem
    Code:
     dst=fopen("Encrypted.txt" ,"wt");
     if(src==NULL){
                   puts("error");
                   getchar();
                   exit(1);
      }
    You might want to check that *dst* is not NULL... ;-)
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,176
    > if(isprint(ch))
    If isprint(ch+1) happens to be false, then your decrypt will FAIL

    Also, some extra braces in your code wouldn't go amiss either. Add any more code to those loops without adding the braces, and it might still compile, but the chances of it doing what you want are 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.

  11. #11
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,398
    Quote Originally Posted by v01d View Post
    Code:
    while(ch!=EOF){ /*encryption*/
                                         ch=fgetc(src); /* ch,chr are int  */
                                         chr=ch+1;
                                         fputc(chr,dst);
                   }
    Code:
    while(ch2!=EOF){ /*decryption*/
                                         ch2=fgetc(src); /*  ch2,chr2 are int   */
                                         chr2=ch2 -1;
                                         fputc(chr2,dst);
                   }
    Why do you process the byte BEFORE you check to see if it's EOF? Your loop is structured wrong.

    Also, naming two variables "chr" and "ch" is massively unclear.

  12. #12
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by v01d View Post

    I think the problem is that for some reason when the chars " "appear the compiler thinks one of them is an EOF and stops.

    can that be the problem or is it something else?
    plz hlp me fix this BUG!
    As a legacy from the days of DOS and 8-inch floppy disks, I/O library routines in Borland and Microsoft Windows compilers (maybe others too, but not GNU/cygwin) usually consider the character ctrl-z (0x1a) to be an "end-of-file" marker for text files. Your input file has 0x19 as its 24th character from the start of the file. This goes into your encrypted file as 0x1a. When you open the encrypted file as a text file and the input routine gets to 0x1a, it returns EOF. (The technical description for this phenomenon is: "That's all she wrote.")

    Whenever you are reading, processing, and/or writing anything other than text, then open the files in binary mode. (Text/binary mode make no difference with Linux GNU and GNU/cygwin compilers, but it doesn't hurt anything, so using "rb" or "wb" mode won't decrease portability.)

    Your original code for encrypting and decrypting could work with binary files.

    Note that the input file in your second example has a 0x1a in the 61st position from the start of the file, so the entire input file is not read. So, no matter what else you do with encrypting/decrypting, it is bound to fail with compilers like the ones I mentioned unless you open the files in binary mode.

    Etc., etc.

    D
    Last edited by Dave Evans; 08-30-2007 at 05:35 PM.

  13. #13
    Registered User
    Join Date
    Aug 2007
    Posts
    7
    Thanks for enlightenment Dave
    the code realy works when run in binary mode...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  4. help with text input
    By Alphawaves in forum C Programming
    Replies: 8
    Last Post: 04-08-2007, 04:54 PM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM