简体   繁体   English

用C将结构写入文件

[英]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). 我有读取项目名称和代码列表并将其写入文件(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. 数据存储在结构对象中,然后使用fwrite写入文件。

The code works fine. 该代码工作正常。 But I need to write a readable data into the text file. 但是我需要将可读数据写入文本文件。

Now the file.txt looks like bellow, 现在file.txt看起来像下面

㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀\\䵏㵈䑜㵅㡸䍏䥔䥆㘸䘠\\㵅㩃䠀䵏㵈䑜㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀䵏㵈\\䑜㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀䵏㵈䑜㵅㡸䍏䥔\\䥆㘸䘠㵅㩃䠀䵏㵈 㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀\\䵏㵈䑜㵅㡸䍏䥔䥆㘸䘠\\㵅㩃䠀䵏㵈䑜㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀䵏㵈\\䑜㵅㡸䍏䥔䥆㘸䘠㵅㩃䠀䵏㵈䑜㵅㡸䍏䥔\\䥆㘸䘠㵅㩃䠀䵏㵈

I am expecting the file should be like this, 我希望文件应该是这样的,

pencil aaaa 铅笔aaaa
Table bbbb 表bbbb
pen cccc 笔抄送
notebook nnnn 笔记本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;
}

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". a)您正在将结构的原始内容转储到文件中,包括指向另一个实例(如果为“ 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). 您不能指望从光盘中读回指针并像使用ptrthis = ptrthis->ptrnext一样使用它(我的意思是,当您在给定的代码段中“使用”它时,它会起作用,但这仅仅是因为该代码段没有任何意义完全没有)。

b) you are writing 2 * 255 bytes of potential crap to the file. b)您正在将2 * 255字节的废话写入文件。 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). 之所以在文件中看到这种奇怪的外观“块”,是因为您将所有255字节的itemname和255字节的dspidc写入光盘..包括终止\\0 (这是块,具体取决于您的编辑器)。 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. 真正的“字符串”在itemnamedspidc的开头是有意义的,后跟\\0 ,然后是内存中的内容。

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 . 您需要查找和了解的术语称为序列化 ,已经有一些库解决了将数据结构转储到磁盘(或网络或其他任何东西)并将其读回的任务,例如tpl

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). 写入255字节的数组大小将向文件写入255字节(无论您在该数组中塞满了什么)。 If you want only the 'textual' portion of that array you need to use a facility that handles null terminators (ie printf , fprintf , ...). 如果只希望该数组的“文本”部分,则需要使用一种处理空终止符的功能(即printffprintf ,...)。

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 (ie memory locations) have application only within the currently executing process. 指针(即内存位置)仅在当前执行的进程内具有应用程序。 Trying to use one process' memory address in another is definitely a bad idea . 试图在另一个进程中使用一个进程的内存地址绝对不是一个好主意

First of all, I would only serialize the data, not the pointers. 首先,我只会序列化数据,而不是指针。

Then, in my opinion, you have 2 choices: 然后,我认为您有2个选择:

  1. write a parser for your syntax (with yacc for instance) 为您的语法编写解析器(例如,使用yacc)
  2. use a data dumping format such as rmi serialization mechanism. 使用数据转储格式,例如rmi序列化机制。

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. 这些解决方案都将是平台无关的,无论是大字节序还是小字节序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM