如何使用 write() 函数将结构写入文件?
How to write a struct to a file using write() function?
我想使用 write() 函数将结构对象写入文件。一定是那个函数。
我从终端输入的是:./main.c output.dat John Doe 45
当我 运行 程序并打开 output.dat 时,有一堆没有意义的字母。请帮助我。
我想要在我的 output.dat 文件中的输出是:John Doe 45
我的代码:
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;
}
当你写结构时,你只写 struct
本身的值。在您的情况下,这些值是指向内存中其他位置的指针,而不是字符串数据。因此,您最终会编写三个指针值的内存地址(在大多数系统上为 12 或 24 字节),这些内存地址并不是那么有用(因为它们适用于当前 运行ning 程序的内存 space , 下一个 运行).
将不一样
您将需要设计一种更有用的序列化格式,实际写出字符串的内容,而不是它们的地址。选项将包括简单的换行符或 NUL
分隔文本、二进制长度前缀文本,或使用第三方库来使其正确,CSV、JSON 或 XML(如果您有雄心壮志) ,某种数据库)。
例如,对于二进制长度的前缀文本,您可以执行如下操作:
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 ...
它允许您通过读取每个字符串长度(固定大小)来读回它,然后使用它来计算必须读取多少字节才能获得该字符串。
你不能只写出对象。您需要单独写出每个内部指针。
像这样:
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);
注意我将 +1
添加到字符串的长度以确保我也写出了终止零。
如果知道每个字段的最大长度,可以尝试将字段做成数组。记得空字节加1
struct Person{
char name[32]; //31 char long + null
char lastName[32]; // 31 char long + null
char age[4]; // 3 char long + null
};
那么你的 fwrite 就可以正常工作了。但是您需要将值 strcpy 到结构中。
strlcpy(human.name, name, sizeof(human.name));
每个字段依此类推。 strlcpy 确保您的字符串以空结尾。
感谢大家,我就这样爱上了它。虽然它并不理想,但它完成了工作 :) :
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;
}
我想使用 write() 函数将结构对象写入文件。一定是那个函数。
我从终端输入的是:./main.c output.dat John Doe 45
当我 运行 程序并打开 output.dat 时,有一堆没有意义的字母。请帮助我。
我想要在我的 output.dat 文件中的输出是:John Doe 45
我的代码:
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;
}
当你写结构时,你只写 struct
本身的值。在您的情况下,这些值是指向内存中其他位置的指针,而不是字符串数据。因此,您最终会编写三个指针值的内存地址(在大多数系统上为 12 或 24 字节),这些内存地址并不是那么有用(因为它们适用于当前 运行ning 程序的内存 space , 下一个 运行).
您将需要设计一种更有用的序列化格式,实际写出字符串的内容,而不是它们的地址。选项将包括简单的换行符或 NUL
分隔文本、二进制长度前缀文本,或使用第三方库来使其正确,CSV、JSON 或 XML(如果您有雄心壮志) ,某种数据库)。
例如,对于二进制长度的前缀文本,您可以执行如下操作:
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 ...
它允许您通过读取每个字符串长度(固定大小)来读回它,然后使用它来计算必须读取多少字节才能获得该字符串。
你不能只写出对象。您需要单独写出每个内部指针。
像这样:
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);
注意我将 +1
添加到字符串的长度以确保我也写出了终止零。
如果知道每个字段的最大长度,可以尝试将字段做成数组。记得空字节加1
struct Person{
char name[32]; //31 char long + null
char lastName[32]; // 31 char long + null
char age[4]; // 3 char long + null
};
那么你的 fwrite 就可以正常工作了。但是您需要将值 strcpy 到结构中。
strlcpy(human.name, name, sizeof(human.name));
每个字段依此类推。 strlcpy 确保您的字符串以空结尾。
感谢大家,我就这样爱上了它。虽然它并不理想,但它完成了工作 :) :
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;
}