Home > Software design >  Fwrite function cuts off data in output .tar file
Fwrite function cuts off data in output .tar file

Time:11-17

I have a piece of code that is designed to replicate the creation of a .tar file albeit a simpler version of it. It will take in 2 .txt files and produce a .tar file of the 2 files. Below is my code for doing so. However when opening the .tar file it is corrupted and sure enough, by viewing the data in a hex editor the data is cut off.

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>

#define  RECORDSIZE  512
#define  NAMSIZ      100
#define  TUNMLEN      32
#define  TGNMLEN      32

struct header {
    char name[NAMSIZ];//needed
    char size[12];//needed
};

int main(int argc, char** argv) {
    //argv[1] file1 argv[2] file2
    char* file1 = argv[1];
    char* file2 = argv[2];
    FILE* f;
    int lSize;
    char temp_length[10];
    char* file1_data, * file2_data;
    int result;

    //char* output_str = (char*)malloc(sizeof)

    f = fopen(file1, "rb");
    if (f == NULL) {
        printf("File error!");
        return 1;
    }
    fseek(f, 0, SEEK_END);
    lSize = ftell(f);
    fseek(f, 0, SEEK_SET);
    file1_data = (char*)malloc(sizeof(char) * lSize);
    if (file1_data == NULL) {
        printf("Memory error!");
        return 1;
    }
    result = fread(file1_data, 1, lSize, f);
    file1_data[result] = '\0';
    fclose(f);
    sprintf(temp_length, "%d", lSize);
    struct header* h1 = malloc(sizeof(struct header));
    strcpy(h1->name, file1);
    strcpy(h1->size, temp_length);
    printf("Name:%s Value:%s\n", h1->name, h1->size);
    printf("File 1 data:%s\n", file1_data);


    f = fopen(file2, "rb");
    if (f == NULL) {
        printf("File error!");
        return 1;
    }
    fseek(f, 0, SEEK_END);
    lSize = ftell(f);
    fseek(f, 0, SEEK_SET);
    file2_data = (char*)malloc(sizeof(char) * lSize);
    if (file2_data == NULL) {
        printf("Memory error!");
        return 1;
    }
    result = fread(file2_data, 1, lSize, f);
    file2_data[result] = '\0';
    fclose(f);
    sprintf(temp_length, "%d", lSize);
    struct header* h2 = malloc(sizeof(struct header));
    strcpy(h2->name, file1);
    strcpy(h2->size, temp_length);
    
    printf("Name:%s Value:%s\n", h2->name, h2->size);
    printf("File 2 data:%s\n", file2_data);

    //allocate mem for output buffer

    int total = sizeof(struct header)   sizeof(struct header)   sizeof(file1_data)   sizeof(file2_data);
    printf("total length %d\n", total);

    f = fopen("Result.tar", "wb");

    //fwrite(input,length,no of ele,output buffer)
    fwrite(h1, sizeof(struct header), 1, f);
    fwrite(file1_data, sizeof(file1_data), 1, f);
    fwrite(h2, sizeof(struct header), 1, f);
    fwrite(file2_data, sizeof(file2_data), 1, f);
    if (fwrite != 0)
        printf("Contents to file written successfully !\n");
    else
        printf("Error writing file !\n");
    fclose(f);
}

First file name: File1.txt Data within:

This is File 1.

Second file name: File2.txt Data within:

This is File 2.
File 2 has more data inside. 

Decoded text output:

File1.txt�ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ31�ÍÍÍÍÍÍÍÍÍThis is File1.txt�ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ63�ÍÍÍÍÍÍÍÍÍThis is 

As observed, File 2's name as well as the subsequent data has been cut off. I've been debugging but I'm unsure where am I going wrong as fwrite does not return a 0 hence, I'm assuming it's successful.

As the print statements are exactly what I expected, I don't think the reading of the data is the issue but rather the fwrite function. Hence I would like to seek advice on it.

CodePudding user response:

The error resids in the way you calculate the total length. Indeed, you do not want to use sizeof(file1_data) as the length of the file. Instead you want to use the value returned when reading in result.

Create two variables file1_length and file2_length. Then populate them with the size of their respective file:

...
size_t f1_len, f2_len;
...
f = fopen(file1, "rb");
if (f == NULL) {
    printf("File error!");
    return 1;
}
fseek(f, 0, SEEK_END);
f1_size = ftell(f);
fseek(f, 0, SEEK_SET);
file1_data = (char*)malloc(sizeof(char) * f1_len);
...

int total = sizeof(struct header)   sizeof(struct header)   f1_len   f2_len;
...
fwrite(h1, sizeof(struct header), 1, f);
fwrite(file1_data, f1_len, 1, f);
fwrite(h2, sizeof(struct header), 1, f);
fwrite(file2_data, f2_len, 1, f);
...

Finally, use these variable as the length of the files' content.

NOTE: The value obtained by sizeof(file1_data) indicate the size of the type. Here, since file1_data is of type char * you get 4.

  • Related