2012-01-18 3 views
0

私はfread関数を使いました。私はバッファサイズ4と "読み込みエラー"を取得しています。割り当てられたバッファが正しいサイズでないのはなぜですか?

なぜbufferfileSizeではありませんか?ここで

は私のコードです:私はプログラムを実行するとき

FILE *fp; 
char* buffer; 
fp = fopen("help.txt","r"); 
if (fp == NULL){ 
    fputs("Can't open Help file, Help.txt",stderr); 
exit(1); 
} 
fseek(fp, 0, SEEK_END); 
long fileSize = ftell(fp); 
rewind(fp); 

buffer = (char*) malloc (sizeof(char)*fileSize); 
if(buffer == NULL){ 
    fputs("Memory Allocation Error",stderr); 
    exit(2); 
} 

size_t result = fread(buffer,1,fileSize,fp); 
if(result != fileSize){ 
fputs("Reading error\n",stderr); 
printf("File Size : %lu\n",fileSize); 
printf("Result : %lu\n",result); 
printf("Buffer Size : %u\n",sizeof(buffer)); 
exit(3); 
} 

fputs(buffer,stdout); 

fclose(fp); 
free (buffer); 

は、これが出力されます。

Reading error 
File Size : 224 
Result : 219 
Buffer Size : 4 
+1

"b" - > 'fopen(" help.txt "、" rb ");を追加してファイルバイナリを開こうとすると、あなたの計算を破壊するような、 – rekire

+0

"目に見えない文字"はシステムの改行がC++改行に変換されているので、数バイトは失われます。バイナリモードで開くとその変換ができなくなります。 –

+0

C++を使用している場合は、ファイルをC++形式(iostreams)で読み込まないようにしてください。 – dreamlax

答えて

3

バッファが正しく割り当てられています。バッファサイズはsizeof(buffer)ではなく、sizeof(char)*fileSizeで計算されます。 bufferがヌルかどうかを確認して、バッファが割り当てられているかどうかをテストできます。そうでない場合は、要求されたサイズ以上のサイズのバッファを正常に割り当てました。

問題は、テキストモードでファイルを開いたことです。そのため、ANSI Cが要求するように、Windowsはファイル内のすべての "\ r \ n"シーケンスを "\ n"に置き換えます。この動作を受け入れるか、ファイルをバイナリモードで開いてfp = fopen("help.txt","rb");を使用して、変更されていない内容をすべて読み取ることができます。あなたは(C++用)mallocの結果をキャスト大丈夫だものの

+0

はい、あなたが入力したのと同じように考えました。代わりの方法(バイナリモードで読み込みたくない場合)は、結果の文字列の '\ n'の数を数え、それを比較するときにサイズを調整することです。 –

5

bufferchar*です。ポインタは4バイトのサイズです(32ビットシステムの場合)。したがって、sizeof(buffer)は常に4を出力します。

特定のサイズのポインタを割り当てた後、それが指しているメモリブロックのサイズが割り当てられたサイズになります。この場合、sizeof(char)*fileSize

編集ああ、あなたの本当のの質問に答えるために、ftellは2つのバイトとしてすべてのCRLFを数え、サイズをバイト単位で報告し、Windowsの問題がありませんでした。これをバッファーで読み取ると、CRLFは1バイトの\nに変換され、結果のテキストのサイズが小さくなります。
(現時点では確認できません)

+0

Windowsはそうしています。私は思った通りです。 –

2

、あなたはalwaysoneあるsizeof(char)、掛ける必要はありません。

sizeof関数は、実行時に割り当てられた変数(すでにfileSizeに保存されている)に割り当てられたバイト数を返しません。静的に割り当てられた変数(例えば、int foo[BAR]; /* sizeof(foo) returns sizeof(int)*BAR bytes */)に期待する方法でのみ動作します。

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

#define BAR 10 

int main() { 
    int foo[BAR]; 
    int *baz; 

    fprintf(stdout, "foo: %zu\n", sizeof(foo)); /* 40 */ 

    baz = malloc(sizeof(int) * BAR); 
    if (baz != NULL) { 
     fprintf(stdout, "baz: %zu\n", sizeof(baz)); /* not 40, but sizeof(int*) */ 
     free(baz); 
    } 
    else { 
     fprintf(stdout, "could not allocate memory for baz\n"); 
     return EXIT_FAILURE; 
    } 

    return EXIT_SUCCESS; 
} 

$ gcc -Wall -o test test.c 
$ ./test 
foo: 40 
baz: 8 

64ビットシステムでは、ポインタは8バイトです。

関連する問題