Re: [Dev-C++] fwrite() & fprintf() -- binary or text ???
Open Source C & C++ IDE for Windows
Brought to you by:
claplace
From: Per W. <pw...@ia...> - 2006-07-12 12:44:30
|
The (almost) only difference between opening a stream as binary or text is that newline is encoded different on different OS, and in text mode, the runtime library will auto-convert newline characters on read/write. Some runtime libraries will also be affected by end-of-file characters, i.e. if file is opened in text mode, they will stop reading when a end-of-file character is found. In binary mode, there are no end-of-file characters, and the file ends when the total number of available characters has been read, i.e. the full size of the input file. fread/fwrite are used to read/write buffers. These can contain binary data, or they can contain normal text data generated with sprintf() or parsed with sscanf() or similar. It is always up to the programmer to know/decide if a file is binary or ascii, and use corresponding methods to extract numbers and text from the file. If the file is binary, you can use fread() to read a number directly into a variable with (note not so portable because of size of an int, and byte order between different architectures): int n; fread(&n,sizeof(n),1,f); If the file is storing the data in ascii format, you can use fscanf() to parse data directly from the file, or fgets() to read a line of text and then extract data with atoi(), sscanf() etc or you can read a block of data with fread() and then manually check for newline charcters etc with strchr() or similar. When writing binary data to file (or reading back) it is almost often best to treat the binary file as a stream of bytes and have the code itself split a binary integer into byte values to read/write. This assures that it is possible to move the binary file between machines of different architecture. The exception is for temporary files that you know never will be moved between machines. Example code to read/write binary data a bit more protable might look like: int write32(unsigned n) { unsigned char buf[4]; buf[0] = (unsigned char)n; buf[1] = (unsigned char)(n >> 8); buf[2] = (unsigned char)(n >> 16); buf[3] = (unsigned char)(n >> 24); return fwrite(buf,4,1,f) == 4; } int read32(unsigned& n) { unsigned char buf[4]; unsigned tmp; if (fread(buf,4,1,f) != 4) return 0; tmp = buf[0]; tmp += ((unsigned)buf[1]) << 8; tmp += ((unsigned)buf[2]) << 16; tmp += ((unsigned)buf[3]) << 24; n = tmp; return 1; } /Per W On Wed, 12 Jul 2006, Farzan Hajian wrote: > Dear Per Westermark, > > Thanks for your answer. It was really amazing ! But that caused a > question. > Do you mean that the ONLY, ONLY, and ONLY difference between text > streams and binary streams is the way that they handle NEWLINE ????? > Before I read your mail ,I used to consider that the difference is > the way that numbers are processed. > > Imagine we have: > > int i=12; > fprintf(file,"%i",i); > > As you know,the result file will have 2 bytes because "12" contains > only 2 ASCII characters.In other words,the number 12 is first stringized > and then it is into the file. But assume we use > > int i=12; > fwrite(&i,sizeof(int),1,file); > > the made file will be 4 bytes long since integers consume 4 bytes.And This assumes a 32-bit architecture, and the file opened in binary mode. Using a 64-bit processor with a 64-bit OS, the file will be 8 bytes large. If the file wasn't opened in binary mode, and i had a binary value looking like a newline, the runtime library would - depending on platform - convert the binary data into garbage. For example, the value 10 should be written as 0x0A, 0x00, 0x00, 0x00 on a 32-bit Intel. In text mode on a Windows machine it will be written as 0x0D, 0x0A, 0x00, 0x00, 0x00 because 0x0A = '\n' and 0x0D = '\r'. The output file got a CR + LF line break. The danger here is that Unix machines doesn't do any text conversion, so on Unix, the source code doesn't need to specify a binary or ascii conversion to work correctly. When such code is ported to Windows, it will fail unless the fopen() calls are fixed. > of course, it is impossible to read this file using a text editor > because the BINARY format of "12" is used and the number is not stringized. Correct. And if you opened the file in text mode, some integers will have a binary representation that will look like newline charactesr - as mentioned above - resulting in a file that no program can correctly read back. Assume that the file was written correctly and contained an integer looking like: 0x0D 0x0A 0x00 0x00 xx xx xx xx which represents the value 13 + 10*256 = 2573 on a 32-bit Intel. When trying to read the file - but opening the file in text mode - the program will instead read: 0x0A 0x00 0x00 xx i.e. the input file will be too short, and we either can't load enough bytes or we will load an incorrect integer because some of the bytes in the integer comes from the following data in the file. > > By reading what you said I'm getting to realized that the idea I had, > was wrong and how numbers are handled is not related to the type of > streams but to the function. Correct! > And if so, is there any other character change in a text stream > (except newline of course!)??? There are no other conversions. However, on some systems, there is the possibility of a end-of-file character stopping the read early. There are ancient OS that doesn't keep track of exact file sizes - just number of blocks. > > Thanks, > > > On Wed, 12 Jul 2006 01:59:48 +0330, Per Westermark <pw...@ia...> > wrote: > > > Hungry Mind > > > > -- > Using Opera's revolutionary e-mail client: http://www.opera.com/mail/ > > > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www23.brinkster.com/noicys/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users > |