I'm having troubles using the fread/fwrite functions to read and write structures to a file. First of all, text written by fwrite is unreadable for me, but from what I see, it is intended to work like this. Is there a way to make it plain text, or it has to be like that?
The other problem is that when I try to read from that file using the fread function, few last elements aren't read.
Further, I'll need this piece of code to sort, directly on the disk, data from a file. Usage of fread/fwrite is compulsory..
#include <stdio.h>
typedef struct camesi {
char camasa[33];
char culoare[33];
int marime;
char material[33];
} cam;
int main() {
FILE *f, *f2;
int i, j, n;
cam a, b, c;
n = 13;
f = fopen ("new.txt", "w+");
f2 = fopen ("asd.txt", "r");
rewind (f2);
for (i = 0; i < n; i++) {
fscanf (f2, "%s%s%d%s", c.camasa, c.culoare, &c.marime, c.material);
printf ("%s\t%s\t%d\t%s\n", c.camasa, c.culoare, c.marime, c.material);
fwrite (&c, sizeof (cam), 1, f);
}
printf ("\n----------------------------------------\n\n");
rewind (f);
for (i = 0; i < n; i++) {
fread (&c, sizeof (cam), 1, f);
printf ("%s\t%s\t%d\t%s\n", c.camasa, c.culoare, c.marime, c.material);
}
return 0; }
This is the output to console:
asdf1 blue 45 skin
asdf2 green 43 skin
asdf3 white 49 skin
asdf4 red 47 skin
asdf5 yellow 54 skin
asdf6 purple 13 skin
asdf7 magenta 74 skin
asdf8 pink 41 skin
asdf9 black 97 skin
asdf10 gray 85 skin
asdf11 orange 26 skin
asdf12 violet 64 skin
asdf13 brown 11 skin
----------------------------------------
asdf1 blue 45 skin
asdf2 green 43 skin
asdf3 white 49 skin
asdf4 red 47 skin
asdf5 yellow 54 skin
asdf6 purple 13 skin
asdf7 magenta 74 skin
asdf8 pink 41 skin
asdf9 black 97 skin
asdf10 gray 85 skin
asdf11 orange 85 skin
asdf11 orange 85 skin
asdf11 orange 85 skin
The first half is the data read from a manually created *.txt file.
The other half is the data read from a file created with the program, using fwrite function.
Content of the original *.txt file:
asdf1 blue 45 skin
asdf2 green 43 skin
asdf3 white 49 skin
asdf4 red 47 skin
asdf5 yellow 54 skin
asdf6 purple 13 skin
asdf7 magenta 74 skin
asdf8 pink 41 skin
asdf9 black 97 skin
asdf10 gray 85 skin
asdf11 orange 26 skin
asdf12 violet 64 skin
asdf13 brown 11 skin
Content of the file created with fwrite function:
asdf1 €M o ёю( Ђ(wїдЂ‚юяяяblue M - skin M `M А&M €ю( HЯПt M asdf2 €M o ёю( Ђ(wїдЂ‚юяяяgreen M + skin M `M А&M €ю( HЯПt M asdf3 €M o ёю( Ђ(wїдЂ‚юяяяwhite M 1 skin M `M А&M €ю( HЯПt M asdf4 €M o ёю( Ђ(wїдЂ‚юяяяred e M / skin M `M А&M €ю( HЯПt M asdf5 €M o ёю( Ђ(wїдЂ‚юяяяyellow M 6 skin M `M А&M €ю( HЯПt M asdf6 €M o ёю( Ђ(wїдЂ‚юяяяpurple M
skin M `M А&M €ю( HЯПt M asdf7 €M o ёю( Ђ(wїдЂ‚юяяяmagenta M J skin M `M А&M €ю( HЯПt M asdf8 €M o ёю( Ђ(wїдЂ‚юяяяpink ta M ) skin M `M А&M €ю( HЯПt M asdf9 €M o ёю( Ђ(wїдЂ‚юяяяblack a M a skin M `M А&M €ю( HЯПt M asdf10 €M o ёю( Ђ(wїдЂ‚юяяяgray a M U skin M `M А&M €ю( HЯПt M asdf11 €M o ёю( Ђ(wїдЂ‚юяяяorange M skin M `M А&M €ю( HЯПt M asdf12 €M o ёю( Ђ(wїдЂ‚юяяяviolet M @ skin M `M А&M €ю( HЯПt M asdf13 €M o ёю( Ђ(wїдЂ‚юяяяbrown M skin M `M А&M €ю( HЯПt M
asdf11 orange 26 skin
Windows可能会将txt文件中的26视为EOF
Is there a way to make it plain text, or it has to be like that?
Yes, it has to be like that because when it was written, the file was filled with the data that was in memory. So it's always like this ie combination of readable and unreadable characters.
In order to understand the behavior of fread/fwrite
i will take the example from your output
asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$asdf1 blue 45 skin$
Now let suppose that the above code is in memory such that asdf1 blue 45 skin
is a structure currently in memory. '$' is just a seperator to represent 7 structures residing in memory. Now if you want to read data from a file into a structure using fread, then the ideal situation is that the file the file was written using fwrite by writing each structure one by one, without any extra byte between them. Only then it can easily be read using fread().
To demonstrate this, here is a simple program that first fill 5 struct objects and then write them onto a file using fwrite. Then it again read those written structures from the file and then fill the C structures with that data.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX 5
struct camesi {
char camasa[33];
char culoare[33];
int marime;
char material[33];
} myStruct;
int main()
{
int i = 0;
FILE *file = NULL;
//Fill a structure with values
memset(&myStruct, 0, sizeof(myStruct));
memcpy(myStruct.camasa, "asdf1", 5);
memcpy(myStruct.culoare, "blue", 4);
myStruct.marime = 45;
memcpy(myStruct.material, "skin", 4);
//Open the file to write
if ((file = fopen("test.txt", "w+")) == NULL) {
printf("Error opening file to write\n");
return -1;
}
for (i = 0; i < MAX; i++)
fwrite(&myStruct, sizeof(myStruct), 1, file);
fclose(file);
//Open the file for read
if ((file = fopen("test.txt", "r")) == NULL) {
printf("Error opening file for read\n");
return -1;
}
//Clear the myStruct from previous values
memset(&myStruct, 0, sizeof(myStruct));
//Read and display
for (i = 0; i < MAX; i++)
{
fread(&myStruct, sizeof(myStruct), 1, file);
printf("%s\t%s\t%d\t%s\n", myStruct.camasa, myStruct.culoare, myStruct.marime, myStruct.material);
//Clear the myStruct from previous value as we will read again in same object in next iteration
memset(&myStruct, 0, sizeof(myStruct));
}
fclose(file);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.