Friday, March 1, 2013

fopen() in r mode problem and solution

#define AllocateMemory 10000
   int main()
{


    char *pBuff;
      FILE *fp;
    int fsize,lBytesRead;

       fp =fopen("clip3.avi","rb");
    if(!fp)
    {
        printf("File open Failed\n");
    }

    pBuff = (char*)malloc(AllocateMemory);
    if(!pBuff)
    {
        printf("mem alloc failed\n");
        exit(0);
    }

    lBytesRead = fread(pBuff,1,AllocateMemory,fp);
    fsize =ftell( fp );


    printf("Hello world! %d \n",fsize);
    free (pBuff);
    return 0;
}

o/p

if  AllocateMemory = 1000
fsize =1000
if  AllocateMemory = 5000
fsize =5000
if  AllocateMemory = 8000
fsize =8001
if  AllocateMemory = 10000
fsize =12228

but in
if  AllocateMemory = 20000
fsize =16384


if  AllocateMemory = 0000
fsize =36384



what is this i don't know  some time size  is increases, some time size is decreases.

 solution open file in 'rb' mode instead of 'r' mode.
  

1) when you use "r" - opening file in normal text format

there is a difference in the way C and other (DOS in my example) represents the End-of-LINE (EOL). In C, the EOL is signalled by a single character, the \n the Newlinefeed. but in DOS, the EOL is signalled by 2 characters, combination of \r-Carriage Return and \n-Newlinefeed.

so if you write a C program to count total number of characters in a file and say, for example, result is 100 (for 10 lines in a file), so when you run it in C, the result will be 100 but when you run the program form DOS, the result will be 110 (10 \r for 10 lines) because it will convert all the \n to \r\n.

2) when using "rb" - opening file in Binary format

but this is the not the case with Binary mode. when reading from disk, it will not convert the \r\ns to \ns. here if you run the program through C IDE, the result will be 110 as shown by DOS also and not 100 because of additional \rs.

 



Text files contain data that are ASCII text. They contain ordinary readable characters such as characters, digits, punctuation, and some special characters such as tabs, line breaks, etc.

A Binary file contains non-readable, or only binary characters. Binary files contain ASCII value of the text.


A text file can be considered as a special case of binary files, where text is encoded in the ASCII format.


Also, text files have lines of text, along with end of line marker at the end of each line.
Whereas, binary files does not. They are not split up into lines or records.

This marker depends upon which operating system you are using.
Macintosh: x'0D'
Unix Based: x'0A'
Windows: x'0D0A'

Reading from a text file is far more easier than reading from a binary file.
Binary file handling is mainly done by using fread and fwrite, which deals with blocks of memories at a time.


When reading a text file, this 'marker' or EOL (End-Of-Line) indicator is translated into '\n' during the read. A binary read will not translate this marker and you will get the character(s) themselves, untranslated.

A binary file can be written directly from a C-structure, ASCII and numbers and all. It can then be read directly into that same structure without translating the data.


The theoretical reason is that "text" means that the file is to be read
in some OS-defined way - e.g., under MSDOS, lines end in CR/LF pairs and
^Z functions as a logical end-of-file marker (that is, data after the ^Z
is not logically part of the file).  Needless to say, neither of these
is relevant under Unix.  And, if all you using is Unix, there is no
difference - so you will not notice any difference - this is a product
of C's Unix heritage. 

 Ref:
http://www.gidforums.com/t-8620.html
http://www.vbforums.com/showthread.php?395162-fopen-s-quot-r-quot-vs-quot-rb-quot-.
http://computer-programming-forum.com/47-c-language/e0b0168a5cca1a7b.htm


No comments:

Post a Comment