Reading binary data into struct with ifstream
As the comment above states, you are probably missing hdr.length and hdr.count.
I tried it with gcc 4.8 and clang 3.5 and it works correctly.
#include <iostream>
#include <fstream>
#pragma pack(push, r1, 1)
struct Header {
char id[15];
int length;
int count;
};
#pragma pack(pop, r1)
int main() {
Header h = {"alalalala", 5, 10};
std::fstream fh;
fh.open("test.txt", std::fstream::out | std::fstream::binary);
fh.write((char*)&h, sizeof(Header));
fh.close();
fh.open("test.txt", std::fstream::in | std::fstream::binary);
fh.read((char*)&h.id, sizeof(h.id));
fh.read((char*)&h.length, sizeof(h.length));
fh.read((char*)&h.count, sizeof(h.count));
fh.close();
std::cout << h.id << " " << h.length << " " << h.count << std::endl;
}
How to read a binary file to a structure in C
You have to pass pointers to have fread()
read data.
void reading(FILE *fp){
Product *obuff = malloc(sizeof(Product));
fread(&obuff->code, sizeof(obuff->code), 1, fp);
fread(&obuff->name, sizeof(obuff->name), 1, fp);
fread(&obuff->quantity, sizeof(obuff->quantity), 1, fp);
fread(&obuff->price, sizeof(obuff->price), 1, fp);
printf("%s %s %d %.2f\n", obuff->code, obuff->name, obuff->quantity, obuff->price);
free(obuff); /* free whatever you allocated after finished using them */
}
Reading a binary file into a struct
Use the struct
module; you need to define the types in a string format documented with that library:
struct.unpack('=HHf255s', bytes)
The above example expects native byte-order, two unsigned shorts, a float and a string of 255 characters.
To loop over an already fully read bytes
string, I'd use itertools
; there is a handy grouper recipe that I've adapted here:
from itertools import izip_longest, imap
from struct import unpack, calcsize
fmt_s = '=5i'
fmt_spec = '=256i'
size_s = calcsize(fmt_s)
size = size_s + calcsize(fmt_spec)
def chunked(iterable, n, fillvalue=''):
args = [iter(iterable)] * n
return imap(''.join, izip_longest(*args, fillvalue=fillvalue))
data = [unpack(fmt_s, section[:size_s]) + (unpack(fmt_spec, section[size_s:]),)
for section in chunked(bytes, size)]
This produces tuples rather than lists, but it's easy enough to adjust if you have to:
data = [list(unpack(fmt_s, section[:size_s])) + [list(unpack(fmt_spec, section[size_s:]))]
for section in chunked(bytes, size)]
Reading binary file and storing it to struct in c
After three hours of research, I finally concluded that the problem was it's missing a NUL
terminator. Using printf with a non-null terminated string
This solved my problem:
...
printf("ChunkID: %.*s\n",4,WAV_HEADER.ChunkID);
printf("ChunkSize: %u\n",WAV_HEADER.ChunkSize);
printf("Format: %.*s\n",4,WAV_HEADER.Format);
...
how to read from binary file into struct c?
If I understand correctly, you're asking if you can do
struct record r;
fread(file, &r, sizeof(r));
or are you forced to use
struct record r;
fread(file, &r.order, sizeof(r.order));
If this is your question, then the answer is: you have to read the fields one-by-one since there may be padding between struct members. Or, if you use a GNU-compatible compiler, you might instruct it not to include any padding by declaring your struct as "packed":
struct record {
// ...
} __attribute__((packed));
But this is not advised unless absolutely necessary (it's not portable).
Also, is your file really a binary file? If not, you should pay attention to newline characters and converting the numbers from text to their actual numeric value.
Read binary file into struct (translating instructions)
Ok, this is not a full answer but I feel comments would be really unreadable here.
The first step is reading the first 12 bytes (three 4-bytes integers), and unpack them so we can check the endianness. Let's try big-endian first
from struct import *
with open(file, "rb") as f:
byte = f.read(12)
header_size, int32key, file_endian = unpack('>3i', byte)
We expect to have int32key
set at 305419896 (= \x12345678). If we get another value then let's switch to little-endian, i.e. change our unpack format string to <3i
.
At this point we can read the rest of the header, with the same logic, and get all the info we need to read data for the first channel. I hope this can be a good start for you.
Reading Binary File into a Structure (C++)
Your struct has almost certainly been padded to preserve the alignment of its content. This means that it will not be 37 bytes, and that mismatch causes the reading to go out of sync. Looking at the way each string is losing 3 characters, it seems that it has been padded to 40 bytes.
As the padding is likely to be between the string and the integers, not even the first record reads correctly.
In this case I would recommend not attempting to read your data as a binary blob, and stick to reading individual fields. It's far more robust, especially if you even want to alter your structure.
Read binary data (from file) into a struct
C struct
s are just about grouping related pieces of data together, they do not specify a particular layout in memory. (Just as the width of an int
isn't defined either.) Little-endian/Big-endian is also not defined, and depends on the processor.
Different compilers, the same compiler on different architectures or operating systems, etc., will all layout structs differently.
As the file format you want to read is defined in terms of which bytes go where, a struct, although it looks very convenient and tempting, isn't the right solution. You need to treat the file as a char[]
and pull out the bytes you need and shift them in order to make numbers composed of multiple bytes, etc.
Read binary file into struct and also problems with endianness
- You must allocate the structure and read data into the structure instead of reading into an pointer directly. If you are going to read only one structure, you won't need to declare pointers for the structure.
printf("%x ", test->magic);
invokes undefined behavior because pointer (automatically converted from the array) is passed to whereunsigned int
is required.
In this case, the observed behavior is because:
Firstly, fread(&test,sizeof(test),1,fp);
read the first few bytes from the file as pointer value.
Then, printf("%02x", test->magic);
printed the first 4-byte integer from the file because test->magic
is (converted to) the pointer to the array placed at the top of the structure, and the address of the array is same as the address of the structure itself, so the address read from the file is printed. One more lucky is that where to read 4-byte integer and address (pointer) from as function arguments are the same.
Finally, you didn't get any output from printf("%x ", test->version);
because the address read from the file is unfortunately in region that is not readable and trying to read there caused Segmentation Fault.
Fixed code:
using namespace std;
#include <stdint.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include "exampleh.h"
struct teststruct test; // allocate structure directly instead of pointer
int main() {
FILE *fp = fopen("C:\\image.dd", "rb"); // open file in binary mode
if (fp == NULL) {
fprintf(stderr, "Can't read file");
return 0;
}
fread(&test,sizeof(test),1,fp); // now structure is read instead of pointer
for (int i = 0; i < 6; i++) {
printf("%02x", (unsigned char)test.magic[i]); // print using proper combination of format and data
}
printf(" ");
printf("%x ", test.version); // also use . instead of ->
fclose(fp);
return 0;
}
Related Topics
How to Get the Path of the Current User's "Application Data" Folder
C# Array.Findallindexof Which Findall Indexof
C# Arrow Key Input for a Console App
How to Bind Datatable to Datagridview in C#
Is There a C# Generic Constraint for "Real Number" Types
Which Blocking Operations Cause an Sta Thread to Pump Com Messages
How to Convert JSON Array to List of Objects in C#
Possible Pitfalls of Using This (Extension Method Based) Shorthand
The Property 'Id' Is Part of the Object's Key Information and Cannot Be Modified
What Could Be Causing a System.Typeloadexception
Pass a Value from One Form to Another
.Net:How to Get the Type of a Null Object
Horizontal Scroll for Stackpanel Doesn't Work