Reputation: 159
This is my code, where I read 256 bytes in "example.txt" and store it in chunk.payload.
I want to be able to first write my struct to "write.txt" then write the contents that I read to "write.txt". I was able to use fwrite
to write everything in chunk.payload to the file, but I am having trouble writing the entire struct to the file.
#define MAXSIZE 256
int main(void){
FILE *fp = fopen("C:\\Users\\alice\\Desktop\\example.txt", "r");
FILE *wr = fopen("C:\\Users\\alice\\Desktop\\write.txt", "w+");
struct packet{
unsigned short block_num;
unsigned short block_size;
unsigned short crc;
unsigned char *payload;
};
/*Create A dummy packet */
struct packet chunk;
chunk.block_num = 0;
chunk.block_size = 256;
chunk.crc = 0x101001;
chunk.payload = malloc(MAXSIZE + 1); // allocating memory
chunk.payload[MAXSIZE] = '\0';
//read first 256 lines and store into chunk.payload
int read = fread(chunk.payload, sizeof(char), MAXSIZE, fp);
// Write struct to write.txt
fwrite(&chunk, sizeof(chunk), 1, wr);
// Write whatever has been read so far to write.txt
fwrite(chunk.payload, sizeof(char), read, wr);
getch();
fclose(fp);
fclose(wr);
return 0;
The way I wrote my call:
fwrite(&chunk, sizeof(chunk), 1, wr);
actually allowed me to compile the code but I ended up having random symbols written to my file before the 256 bytes that i read were written to my file
What is the correct method to do this?
Upvotes: 3
Views: 4817
Reputation: 109
Your chunk structure contains a pointer to the payload. These are the "junk" characters you're seeing. Since you're limiting the payload size to MAXSIZE anyway, you could just set payload to be statically sized instead:
struct packet{
unsigned short block_num;
unsigned short block_size;
unsigned short crc;
unsigned char payload[MAXSIZE];
};
This has the added advantage of not saving a pointer, using the heap, etc. In this situation your first fwrite will write the entire thing, including the payload and your second fwrite isn't needed.
If you need to have arbitrary sized payloads then you can use this old trick:
struct packet{
unsigned short block_num;
unsigned short block_size;
unsigned short crc;
unsigned char payload[0];
};
/*Create A dummy packet */
struct packet *chunk;
chunk = (struct packet *)malloc(sizeof(struct packet) + packetsize + 1);
chunk->block_num = 0;
chunk->block_size = 256;
chunk->crc = 0x101001;
chunk->payload[packetsize] = '\0';
Then you'd need to update your first fwrite to be:
// Write struct to write.txt
fwrite(chunk, sizeof(*chunk) + packetsize, 1, wr);
NOTE: You still don't need the second fwrite in this case.
Also, don't forget the add one for the NUL terminator if you want to save that too.
Upvotes: 0
Reputation: 1323
Payload is character datatype and other members of the structures are integer. You are creating text file. So, convert the integer to character and then write into write.txt
Like this also possible;
typedef struct Test
{
int a,b,c, d;
}Ref;
main () {
fp=fopen("/home/test_prog/sampe.txt", "w+");
sprintf (data, "%d %d %d %d", example.a, example.b, example.c, example.d);
fwrite (data, sizeof(char), strlen(data) , fp );
fclose (fp);
}
Upvotes: 0
Reputation: 1477
Your first fwrite is attempting to write the binary contents of the packet structure to your write.txt file:
// Write struct to write.txt
fwrite(&chunk, sizeof(chunk), 1, wr);
The second:
// Write whatever has been read so far to write.txt
fwrite(chunk.payload, sizeof(char), read, wr);
is writing the content of your malloc'd payload. I don't think you want to write the binary to the file. If you want to write packet struct values as text to the file before the payload, you will have to do something like fprintf them one by one e.g.
// write contents of 'chunk' to text file
fprintf( wr, "block_num= %d\n", chunk.block_num );
...
fwrite(chunk.payload, sizeof(char), read, wr);
also note that your payload text will not be properly zero-terminated if read is less than MAXSIZE.
Upvotes: 1
Reputation: 15511
fread
and fwrite
are generally for reading/writing binary data. You want to write text data, which is usually done with fscanf
or fgets
for input, and fprintf
for output.
Upvotes: 0