2016-04-07 11 views
0

Ich habe eine Zuordnung, wo ich eine Word-Datei (.doc) nehmen, Dateisystem-IO-Code zum Lesen der Datei verwenden soll die Datei in zwei Hälften teilen und jede Hälfte auf zwei separate schreiben Dateien im Binärmodus. Ich schrieb den folgenden Code und es läuft erfolgreich und produziert die zwei Dateien, sogar die Größe der Dateien sind die Hälfte des Originals. Wenn ich jedoch die Word-Datei öffne, kommen sie heraus, um beschädigt zu werden. Das funktioniert gut mit einer TXT-Datei, aber mein Lehrer sagte, es sollte für .doc und .zip-Dateien ohne Dateibeschädigung funktionieren. stimmt etwas mit meinem Code nicht? Danke für jede Hilfe, die ich wirklich schätze.Zerlegen einer Binärdatei in Datei in C ohne Korruption

#include <stdio.h> 

int main (int argc, char **argv) 
{ 
    char *fileName = "1.doc"; 
    char *buffer = "a"; 
    int chunk; 

    FILE *fd; 
    fd = fopen (fileName, "rb"); 
    if (fd == NULL); 
     ferror ("error"); 
    fseek (fd, 0, SEEK_END); 
    chunk = ftell (fd)/2; 
    rewind (fd);    //open file, get size, set chunk = to half the file, rewind back to begining of file 

    fread (buffer, chunk, 1, fd); 
    fclose (fd);    //read the first half of the file into buffer 

    fd = fopen ("1_1.doc", "wb"); 
    fwrite (buffer, chunk, 1, fd); 
    fclose (fd);    //create new file, write the contents of buffer into it 

    fd = fopen (fileName, "rb"); 
    fseek (fd, chunk, SEEK_SET); 
    fread (buffer, chunk, 1, fd); 
    fclose (fd);    //reopen original file, go to half the file, read the remaining half of the file and store in buffer 

    fd = fopen ("1_2.doc", "wb"); 
    fwrite (buffer, chunk, 1, fd); 
    fclose (fd);    //create a new file, write the second half of the file into it 

    return 0; 

} 

Ich habe beide Varianten von

versucht
fwrite(buffer, chunk, 1, fd); 

UND

fwrite(&buffer, chunk, 1, fd); 
+1

Was passiert, wenn 'fd = NULL'? (Hinweis - es wird nicht beendet). Wie viel Speicher ist für 'Puffer' reserviert? –

+1

Ich sehe nicht, dass Sie keinen Speicher für den Puffer reservieren - daher undefiniertes Verhalten – John3136

+4

'doc' und' zip' Dateien haben eine interne Struktur. Wenn Sie die Datei in zwei Hälften teilen, wird die Datei beschädigt und unbrauchbar.Vielleicht hast du deinen Lehrer falsch verstanden. – Ari0nhh

Antwort

0

Sie haben ein halbes Byte verloren, im Durchschnitt.

Wenn die Dateigröße gerade ist, kann die Datei in zwei gleiche Hälften geteilt werden.

Wenn die Dateigröße ungerade ist, muss ein Chunk ein Byte größer sein.

size_t length = ftell(fd); 
size_t chunk1 = length/2; 
size_t chunk2 = length - chunk1; 

Und Sie müssen wirklich Platz für die Chunks reservieren; buffer kann nicht mehr als 2 Bytes enthalten, ohne auf anderen Speicher zu kritzeln, und diese 2 Bytes könnten im Nur-Lese-Speicher sein.

1

Sie haben eine Reihe von Fragen, die primären, von denen Sie Puffer verwenden, ohne das Zuweisen von Speicher und versuchen, an die Adresse des angegebenen Stringliteral"a" in Nur-Lese-Speicher zu schreiben.

dieses Problem zu beheben, müssen Sie:

#include <stdlib.h> 
... 
    char *buffer = NULL; 
... 
    chunk = ftell (fd)/2; 

    if ((buffer = malloc (chunk * sizeof *buffer)) == NULL) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

Ihre Nutzung von ferror falsch ist, es ein FILE * Argument, kein char *:

fd = fopen (fileName, "rb"); 
    if (fd == NULL) { 
     ferror (fd); 
     return 1; 
    } 

Schließlich, vergessen Sie nicht frei der Speicher, den Sie zuweisen, wenn er nicht mehr benötigt wird:

setzt sie alle zusammen, können Sie so etwas wie die folgenden tun:

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

int main (void) 
{ 
    char *fileName = "1.doc"; 
    char *buffer = NULL; 
    int chunk; 

    FILE *fd; 

    /* open file, get size, set chunk = to half the file, 
    * allocate memory, rewind back to begining of file 
    */ 
    fd = fopen (fileName, "rb"); 
    if (fd == NULL) { 
     ferror (fd); 
     return 1; 
    } 
    fseek (fd, 0, SEEK_END); 
    chunk = ftell (fd)/2; 

    if ((buffer = malloc (chunk * sizeof *buffer)) == NULL) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

    rewind (fd); 

    /* read the first half of the file into buffer */ 
    fread (buffer, chunk, 1, fd); /* you should check return of each read */ 
    fclose (fd); 

    /* create new file, write the contents of buffer into it */ 
    fd = fopen ("1_1.doc", "wb"); 
    if (fd == NULL) { 
     ferror (fd); 
     return 1; 
    } 
    fwrite (buffer, chunk, 1, fd); /* you should check return of each write */ 
    fclose (fd); 

    /* reopen original file, go to half the file, read the 
    * remaining half of the file and store in buffer 
    */ 
    fd = fopen (fileName, "rb"); 
    if (fd == NULL) { 
     ferror (fd); 
     return 1; 
    } 
    fseek (fd, chunk, SEEK_SET); 
    fread (buffer, chunk, 1, fd); /* you should check return */ 
    fclose (fd); 

    /* create a new file, write the second half of the file into it */ 
    fd = fopen ("1_2.doc", "wb"); 
    if (fd == NULL) { 
     ferror (fd); 
     return 1; 
    } 
    fwrite (buffer, chunk, 1, fd); /* check return */ 
    fclose (fd); 

    free (buffer); /* free allocated memory */ 

    return 0; 

} 

Eingabedatei

$ cat 1.doc 
Mon Feb 29 10:06:59 CST 2016 
Mon Feb 29 10:06:59 CST 2016 
Mon Feb 29 10:06:59 CST 2016 
Mon Feb 29 10:06:59 CST 2016 

Beispiel Verwendung/Ausgabedateien

$ ./bin/binread 

$ l 1* 
-rw-r--r-- 1 david david 116 Apr 6 23:17 1.doc 
-rw-r--r-- 1 david david 58 Apr 6 23:18 1_1.doc 
-rw-r--r-- 1 david david 58 Apr 6 23:18 1_2.doc 

$ cat 1_1.doc 
Mon Feb 29 10:06:59 CST 2016 
Mon Feb 29 10:06:59 CST 2016 

Lassen Sie mich wissen, wenn Du hast Fragen.