简体   繁体   English

如何使用write()函数将结构写入文件?

[英]How to write a struct to a file using write() function?

I want to write a struct object to a file using the write() function. 我想使用write()函数将struct对象写入文件。 It has to be that function. 它必须是那个功能。

My input from terminal is: ./main.c output.dat John Doe 45 我从终端输入的是:./main.c output.dat John Doe 45

When I run the program and open the output.dat there are bunch of letters that don't make sense. 当我运行程序并打开output.dat时,会出现一堆没有意义的字母。 Please help me. 请帮我。

The output I want in my output.dat file is: John Doe 45 我想要的output.dat文件中的输出是:John Doe 45

My code: 我的代码:

struct Person{
  char* name;
  char* lastName;
  char* age;
};

int main(int argc, char** argv){

    struct Person human;
    /* get the argument values and store them into char*         */
    char* fileName = argv[1];
    char* name = argv[2];
    char* lastName = argv[3];
    char* age = argv[4];

    /* set the values of human object */
    human.name = name;
    human.lastName = lastName;
    human.age = age;

    /* open the file */
    int file = 0;
    file = open(fileName, O_RDWR); /* I want to have read&write set! */
    write(file, &human, sizeof(human));
    close(file);


    return 0;
}

When you write the struct, you only write the values in the struct itself. 编写该结构时,只能在该struct本身中写入值。 In your case, those values are pointers to other places in memory, not the string data. 在您的情况下,这些值是指向内存中其他位置的指针,而不是字符串数据。 Thus, you end up writing three pointers worth of memory addresses (12 or 24 bytes on most systems) that aren't all that useful (since they apply to the memory space of the currently running program, which won't be the same on the next run). 因此,您最终编写了三个指针,这些指针的内存地址(在大多数系统上为12或24字节)并不是全部有用(因为它们适用于当前正在运行的程序的内存空间)下一次运行)。

You're going to need to design a more useful serialization format that actually writes out the contents of the strings, not their addresses. 您将需要设计一种更有用的序列化格式,该格式实际上写出字符串的内容 ,而不是它们的地址。 Options would include simple newline or NUL separated text, binary length prefixed text, or with third party libraries to get it right, CSV, JSON, or XML (if you're feeling ambitious, a database of some sort). 选项包括简单的换行符或NUL分隔的文本,二进制长度的前缀文本,或带有第三方库的CSV,JSON或XML(如果您有野心,请使用某种数据库)。

For example, with binary length prefixed text, you might do something like: 例如,使用二进制长度的前缀文本,您可以执行以下操作:

uint32_t len;

len = strlen(name);
write(file, &len, sizeof(len));
write(file, human.name, len);
len = strlen(lastName);
write(file, &len, sizeof(len));
write(file, human.lastName, len);
... repeat for age ...

which allows you to read it back in by reading each string length (fixed size), then using it to figure out how many bytes must be read to get the string. 它允许您通过读取每个字符串长度(固定大小)来重新读回它,然后使用它来计算必须读取多少字节才能获得该字符串。

You can't just write out the object. 您不能只写出对象。 You need to write out each of the internal pointers individually. 您需要分别写出每个内部指针。

Something like this: 像这样:

file = open(fileName, O_RDWR); /* I want to have read&write set! */

write(file, human.name, std::strlen(human.name) + 1);
write(file, human.lastName, std::strlen(human.lastName) + 1);
write(file, human.age, std::strlen(human.age) + 1);

close(file);

Notice I add +1 to the length of the strings to make sure I also write out the terminating zero. 注意,我在字符串的长度上添加了+1 ,以确保我也写出了终止的零。

If you know the maximum length of each field, you can try making the fields an array. 如果您知道每个字段的最大长度,则可以尝试使这些字段成为数组。 Remember to add 1 for null byte 记住为空字节加1

struct Person{
  char name[32]; //31 char long + null 
  char lastName[32]; // 31 char long + null
  char age[4]; // 3 char long + null
};

Then your fwrite will work fine. 然后,您的fwrite将正常工作。 But you need to strcpy the values in to the struct. 但是您需要将值存储在结构中。

strlcpy(human.name, name, sizeof(human.name));

and so on for each field. 对于每个字段,依此类推。 strlcpy makes sure your string is null terminated. strlcpy确保您的字符串以null终止。

Thanks to all, I sloved it like this. 多亏了所有人,我才这样喜欢它。 Although it is not ideal it gets the job done :) : 虽然不理想,但可以完成工作:):

struct Person{
   char name[20];
   char lastName[20];
   char age[20];
};

int main(int argc, char** argv){

   struct Person human;
   /* get the argument values and store them into char*         */
   char* fileName = argv[1];
   char* name = argv[2];
   char* lastName = argv[3];
   char* age = argv[4];

   sprintf(human.name,name);
   sprintf(human.lastName,lastName);
   sprintf(human.age,age);

   /* open the file */
   int file = 0;
   file = open(fileName, O_RDWR); /* I want to have read&write set! */
   write(file, &human, sizeof(human));
   close(file);


   return 0;
}

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

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