Writing data to file in C [Serialization] - c

I have a struct that I want to save in a data file.
typedef struct Photo {
char name[20];
char description[100];
} photo;
I'd like to be able to save many of these structs in a file, much like a database. The only way I can see in doing that would be through fwrite() which has problems when it comes to platform mobility, and to just write photo->name, photo->description as ascii. I would really like to avoid having to parse all of the raw text data. Is there another way to do it?

I couldn't really understand what you are asking but you can also write to files using fprintf.
And if you are asking how to store the data in the file for faster lookup, use hash tables, at the start of the file have a table which points to memory locations for the structure along with a hash value(of the name parameter).
When querying the file all you have to do is match the hash value and then jump to that specific location.

Related

Storing data in filename vs inside file

What is difference between, when I store any data on filename and not inside file.
I'm tempted to say that using a key-value store is the direction you want to take but without having broader context and going with the assumption that you do want to use files and not yet not consume data blocks, you could store these values as extended attributes of the file. If the number of attributes are small enough, they will fit into the inode and not use up data blocks.i.e. your file size will still be zero bytes.
I suggest you to use case B. Maybe you lose some same but it's the better thing.
In scientific implications: in the first case you memorize in an special portion of the memory that it is care to name of file in the second case you use the file itself. On widows you cannot memorie name major than 255 chars.
Why do you not create a file.json and inside a Json format?

Print a structure in a String format in C

I one of my assignment, I have a task to print the below whole structure in a string format.
Struct test
{
int a,
char char1,char2;
}
output should be: Structure is a=10,char1=b,char2=c;
I know it is very simple by using
printf("Structure is a=%d,char1=%c, char2= %c", s.a,s.char1,s.char2);
But in real-time, I have a lot of big structures and I cannot write printf statements with access specifiers for each element of structure. Is there any other way to print the whole structure with just specifying the structure variable or some other?
There's no way to do this in pure C. Some languages support this via a concept called reflection, but it's not available in C.
Code-that-writes-code is your best bet. Write a script that finds all your structs and builds functions to printf them.
One possible solution I can think of is that you can take the help of the fread funtion using which you can save the whole content of the structure at once into a, say temporary file. Using:
fread(&STRUCTURE_OBJECT, sizeof(YOUR_STRUCTURE), 1, FILE_POINTER);
Where STRUCTURE_OBJECT is the name of a data element of your strucure.
And then use linux based commands like "cat" and "piping" etc for the quick glance of the output.

Creating a FILE structure using a byte array

The SDL_image API allows you to pass in a FILE* and get an SDL_Surface*.
Currently, I'm designing a map archive.
One of the files is a tileset. It will be a PNG image (Great format with it's lossless compression).
I'm reading all the bytes from the file and putting them into a buffer (a byte array).
How would I go about creating a FILE* out of a byte array?
I don't care if I have to modify anything inside the FILE structure that's meant to be private, that was my initial approach, but I was facing difficulties figuring out what a couple of the members of the struct are for. (I'm referring to the _iobuf struct)
Edit
You have to understand that I'm using zlib, meaning that when reading from the uncompressed files in the archive, I'm using the function unzReadCurrentFile.
I don't know if there's a way to get a FILE* directly while using zlib.
You can't. It's impossibru. A FILE* is just that- a file. You can't do anything about the fact that the SDL API uses C I/O and therefore is approximately as useful as a dead fish.

How to write dynamically allocated structure to file

I have a complex structure in a C program which has many members that are allocated memory, dynamically. How do I write this structure to a text / binary file? How will I be able to recreate the entire structure from the data read from the file.
struct parseinfo{
int varcount;
int termcount;
char **variables;
char **terminals;
char ***actions;
};
The members variables, terminals and actions are all dynamically allocated and I need to write this structure to a file so that I could reconstruct the structure later.
You must write to this structure Serialize and Deserialize functions, you can't write this structure to file as raw data because you have allocated pointers on a heap and this not make sense to save this values on file.
Short: Not in an automated way.
In essence, it depends highly on the semantics of your structure.
If the data fields inside specify the length of certain arraiys inside it,
you can reconstruct the struct.
But you have to be careful to "beleive" the values. (possible cause of stack overflow (nice word)) if you believe that there are 2^34 entries in an array.
But otherwise it is just going tru every member (pain)
You could search a little about ASN.1 and TLV-structs.
Here are some suggestions for binary serialization:
You can serialize a string either a la C (write the terminating '\0') or
by writing the size (say, an int) followed by the contents.
You can serialize an array of strings by writing the length of the array
followed by the strings.
If it's possible that you deserialize the file on a different
architecture (different int size, different endianness...), then take
care to carefully specify the binary format of the file. In such a case
you may want to take a look at the XDR serialiaztion standard.
For ASCII serialization, I like the JSON format.
The way I would suggest to do it is to think about what does it take to create the items in the first place?
When it comes to the char **variables; char **terminals; char **actions you're obviously going to have to figure out how to declare those and read them in but I don't think you can inject a /0 into a file (EOF character??)
How would you like to see it written to the file? Can you provide a sample output how you think it should be stored? Perhaps one item per line in a file? Does it need to be a binary file?

Writing structure into a file in C

I am reading and writting a structure into a text file which is not readable. I have to write readable data into the file from the structure object.
Here is little more detail of my code:
I am having the code which reads and writes a list of itemname and code into a file (file.txt). The code uses linked list concept to read and write data.
The data are stored into a structure object and then writen into a file using fwrite.
The code works fine. But I need to write a readable data into the text file.
Now the file.txt looks like bellow,
㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀\䵏㵈䑜㵅㡸䍏䥔䥆㘸䘠\㵅㩃䠀䵏㵈䑜㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀䵏㵈\䑜㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀䵏㵈䑜㵅㡸䍏䥔\䥆㘸䘠㵅㩃䠀䵏㵈
I am expecting the file should be like this,
pencil aaaa
Table bbbb
pen cccc
notebook nnnn
Here is the snippet:
struct Item
{
char itemname[255];
char dspidc[255];
struct Item *ptrnext;
};
// Writing into the file
printf("\nEnter Itemname: ");
gets(ptrthis->itemname);
printf("\nEnter Code: ");
gets(ptrthis->dspidc);
fwrite(ptrthis, sizeof(*ptrthis), 1, fp);
// Reading from the file
while(fread(ptrthis, sizeof(*ptrthis), 1, fp) ==1)
{
printf("\n%s %s", ptrthis->itemname,ptrthis->dspidc);
ptrthis = ptrthis->ptrnext;
}
Writing the size of an array that is 255 bytes will write 255 bytes to file (regardless of what you have stuffed into that array). If you want only the 'textual' portion of that array you need to use a facility that handles null terminators (i.e. printf, fprintf, ...).
Reading is then more complicated as you need to set up the idea of a sentinel value that represents the end of a string.
This speaks nothing of the fact that you are writing the value of a pointer (initialized or not) that will have no context or validity on the next read. Pointers (i.e. memory locations) have application only within the currently executing process. Trying to use one process' memory address in another is definitely a bad idea.
The code works fine
not really:
a) you are dumping the raw contents of the struct to a file, including the pointer to another instance if "Item". you can not expect to read back in a pointer from disc and use it as you do with ptrthis = ptrthis->ptrnext (i mean, this works as you "use" it in the given snippet, but just because that snippet does nothing meaningful at all).
b) you are writing 2 * 255 bytes of potential crap to the file. the reason why you see this strange looking "blocks" in your file is, that you write all 255 bytes of itemname and 255 bytes of dspidc to the disc .. including terminating \0 (which are the blocks, depending on your editor). the real "string" is something meaningful at the beginning of either itemname or dspidc, followed by a \0, followed by whatever is was in memory before.
the term you need to lookup and read about is called serialization, there are some libraries out there already which solve the task of dumping data structures to disc (or network or anything else) and reading it back in, eg tpl.
First of all, I would only serialize the data, not the pointers.
Then, in my opinion, you have 2 choices:
write a parser for your syntax (with yacc for instance)
use a data dumping format such as rmi serialization mechanism.
Sorry I can't find online docs, but I know I have the grammar on paper.
Both of those solution will be platform independent, be them big endian or little endian.

Resources