Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Fwrite function cuts off data in output .tar file

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading