Reputation: 154
I want to write a struct object to a file using the write() function. It has to be that function.
My input from terminal is: ./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. Please help me.
The output I want in my output.dat file is: 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;
}
Upvotes: 1
Views: 1695
Reputation: 154
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;
}
Upvotes: 0
Reputation: 111
If you know the maximum length of each field, you can try making the fields an array. Remember to add 1 for null byte
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. 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.
Upvotes: 1
Reputation: 48605
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.
Upvotes: 1
Reputation: 155323
When you write the struct, you only write the values in the struct
itself. 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).
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).
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.
Upvotes: 5