2016-04-07 10 views
0

私はワードファイル(.doc)を使用しなければならないファイルシステムのIOコードを使用してファイルを半分に分割し、バイナリモードのファイル。私は以下のコードを書いて、正常に実行して2つのファイルを生成します。ファイルのサイズが元のファイルの半分であっても。しかし、私が単語ファイルを開くために行くとき、彼らは壊れて出てくる。これは.txtファイルでうまく動作しますが、インストラクターはファイルの破損がない.docファイルと.zipファイルで動作するはずだと言いました。私のコードに何か問題がありますか?助けてくれてありがとう、本当に感謝しています。Cでバイナリファイルを破損せずに分割する

#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; 

} 

は、私はあなたが、平均して、半分のバイトを失ってしまった

fwrite(buffer, chunk, 1, fd); 

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

'fd = NULL'の場合はどうなりますか? (ヒント - 終了しません)。どのくらいのメモリが 'buffer'に割り当てられていますか? –

+1

私はあなたがバッファのためのメモリを割り当てているとは思わない - したがって、未定義の振る舞い – John3136

+4

'doc'と' zip'ファイルは内部構造を持っています。ファイルを半分に分割するだけでファイルが破損し、ファイルを使用できなくなります。おそらくあなたはあなたのインストラクターを誤解したでしょう。 – Ari0nhh

答えて

0

の両方のバリエーションを試してみました。

ファイルサイズが偶数の場合、ファイルは2つの等しい半分に分割できます。

ファイルサイズが奇数の場合、1つのチャンクは1バイト大きくなければなりません。

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

実際にチャンクのためのスペースを割り当てる必要があります。 bufferは、2バイト以上を他のメモリに書き込むことなく保持することはできず、その2バイトは読み出し専用メモリに存在する可能性があります。

1

メモリを割り当てずにバッファを使用していて、宣言されたの文字列リテラル"a"の読み取り専用メモリに書き込むことを主な目的とした多数の問題があります。

この問題を修正するには、以下を行う必要があります

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

最後に、解放することを忘れないでください:ferror

#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; 
    } 

ご利用が間違っている、それはFILE *引数、ないchar *を取ります不要になったときに割り当てるメモリ:

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

次のような何かを行うことができ、それをすべて一緒に置く:

#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; 

} 

入力ファイル

$ 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 

使用例/出力ファイル

$ ./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 

なら、私を知ってみましょうあなたは質問があります。

関連する問題