![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#11 |
|
Programmer
Join Date: Feb 2006
Posts: 36
Rep Power: 0
![]() |
No that's not the case! Bad joke maybe...
While I am here, I will ask something: How do I read a unsigned int (0-255) stored in 8-bits from the file? Is this the only way: unsigned char buf[buf_size]; file.read (reinterpret_cast<char *> (&buf), buf_size); Plus the compile error I was getting from the first post ... why isn't that allowed or what was my mistake: // error: expected primary-expression before "unsigned"
// error: expected `;' before "unsigned"
//cout << unsigned int (test) << endl;Thanks |
|
|
|
|
|
#12 |
|
Professional Programmer
![]() Join Date: Sep 2005
Posts: 419
Rep Power: 3
![]() |
>Is this the only way:
No. In fact, that's an exceptionally poor way if portability is a concern. A decidedly better implementation is also more manual. You read single bytes and build your value manually. Better yet, don't use binary files at all. Text is generally accepted as superior most of the time. >why isn't that allowed or what was my mistake: You can't use the function style cast with multi-keyword types: cout << (unsigned int)test << endl;
__________________
Even if the voices aren't real, they have some pretty good ideas. |
|
|
|
|
|
#13 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
If this is what you're talking about,
unsigned int (test) Please name your compiler and give a short example of the binary information in your file (example: 0xff 0x01 0xcc, or 11111111 00000001 11001100). These things are bits. They are not signed or unsigned until you try to use them in a certain way. ANSI C and C++ do not require a specific implementation of the char type. This is what some of your respondents have been trying to tell you. It matters when you extend the size of a char to a larger entity (such as an int). If it's considered unsigned the least significant byte of the int will contain the binary pattern in the char and the more significant bytes will contain zeroes. If it's considered signed, the sign will be extended into the more significant bytes of the int. Thus, 11111111, if considered signed, will result in a (4 byte) int of 11111111 11111111 11111111 11111111, still -1. If it's considered unsigned, it will result in 00000000 00000000 00000000 11111111, still 255. You can determine this by examination, or you can read the documentation for your compiler. VC++ happens to have an option that will allow you to change the default type, as to signed or unsigned. Who knows about the compiler you have. I suppose de Shadder do, but he's out on a case. EDIT: Woops, La Narue got here before me. She is way more knowledgeable than I about these things, especially since I mentally live in a prestandard world, yet.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#14 |
|
Programmer
Join Date: Feb 2006
Posts: 36
Rep Power: 0
![]() |
Data I'm trying to read is mostly headers or such information that describes file format... Usually it's a series of bits (flags) or sometimes mix of chars (a-z) and ints uints longs and such...
For example a wav file header (riff file format) is: The canonical WAVE format starts with the RIFF header: Offset Length Contents 0 4 bytes 'RIFF' 4 4 bytes <file length - 8> 8 4 bytes 'WAVE' (The '8' in the second entry is the length of the first two entries. I.e., the second entry is the number of bytes that follow in the file.) Next, the fmt chunk describes the sample format: 12 4 bytes 'fmt ' 16 4 bytes 0x00000010 // Length of the fmt data (16 bytes) 20 2 bytes 0x0001 // Format tag: 1 = PCM 22 2 bytes <channels> // Channels: 1 = mono, 2 = stereo 24 4 bytes <sample rate> // Samples per second: e.g., 44100 28 4 bytes <bytes/second> // sample rate * block align 32 2 bytes <block align> // channels * bits/sample / 8 34 2 bytes <bits/sample> // 8 or 16 Finally, the data chunk contains the sample data: 36 4 bytes 'data' 40 4 bytes <length of the data block> 44 bytes <sample data> Or an mp3 file has a frame sync (11 bits all set to 1)... followed with other bits (flags)... I thought It's easy to read and interpret them, but I got stuck with those implementation defined features... And yes I know that gcc has -signed or similar option, but I try to avoid that... Bye... |
|
|
|
|
|
#15 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
Here is an example of generating a .wav file header and attaching explorer.exe to it, to play it as a .wav file. If this doesn't give you concrete ideas, post back. I have an example of reading a .bmp file header, which is similar to what you defined. I'll dig it up and post it, if necessary. It reads the header and fills in a struct with the various entities, which are mixed characters, and other values (bits per pixel, etc.).
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#16 |
|
Programmer
Join Date: Feb 2006
Posts: 36
Rep Power: 0
![]() |
Do you suggest then to use:
// write os.write ((const char *) &chunk.formatSize, 4); // read is.read ((const char *) &chunk.formatSize, 4); Is there any difference between: os.write ((const char *) &chunk.formatSize, 4); // and os << chunk.formatSize; Thanks... |
|
|
|
|
|
#17 |
|
Professional Programmer
Join Date: May 2006
Location: Maryland, USA
Posts: 306
Rep Power: 3
![]() |
I think you need to do some more reading the os.write line will write 4 characters (how every many bytes each is char is) from the starting at the address of chunk.formatSize. The second one will write chunk.formatSize to the stream, whatever it is.
The best way to read in binary data like this is to used fixed width types. Have a look at stdint.h and build a structure that matches the header described above. |
|
|
|
|
|
#18 |
|
Resident Grouch
![]() ![]() ![]() ![]() ![]() ![]() Join Date: Jun 2005
Posts: 6,453
Rep Power: 10
![]() |
GameEnder is correct. Sometimes the easy path is the long way home. 00001 is the same value as 1, but if you're writing on the head of a pin with a piece of chalk, you may want to get selective.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code. Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers |
|
|
|
|
|
#19 | |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,207
Rep Power: 5
![]() |
Quote:
The terms "implementation-defined behavior" (curse that impure Americanized spelling), "undefined behavior", "unspecified behavior", and several others are given very specific definitions in the C++ standard. For example, clause 1.3.5 in the standard defines "implementation-defined behavior" as "behavior, for a wellformed program construct and correct data, that depends on the implementation and that each implementation shall document". Then, later, section 7.1.5.2 states "It is implementation-defined whether bit-fields and objects of char type are represented as signed or unsigned quantities. The signed specifier forces char objects and bit-fields to be signed; it is redundant with other integral types." |
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Casting a struct to s aimilar struct | shoeyfighter | C | 6 | Oct 27th, 2006 2:59 PM |
| Question regarding Malloc() and Type casting | sparda | C | 6 | Sep 29th, 2005 4:12 AM |