私は C 文字列とストリームをいじって、それらをよりよく理解しています。入力ファイルから固定サイズのデータ ブロックをバッファーに読み取り、バッファーの内容を中間ストレージに格納するこのテスト プログラムがあります (この場合、ストレージに 3 つの異なる "読み取り" を格納できるようにします)。次に、読み取った文字列と中間ストレージ内の文字列の 1 つを出力ファイルに書き込みます。
これに関する注意: 各反復では、中間ストレージの最初の 2 つの位置を使用し、2 番目の「格納された文字列」をファイルに書き込みます。
コード:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 3
#define BUFFER_SIZE 5
int main(int argc, char** argv) {
FILE* local_stream_test = fopen("LOCAL_INPUT_FILE","r");
FILE* local_output_test = fopen("LOCAL_OUTPUT_TEST","w");
if(!local_stream_test) {
puts("!INPUT FILE");
return EXIT_FAILURE;
}
if(!local_output_test) {
puts("!OUTPUT FILE");
return EXIT_FAILURE;
}
char my_buffer[BUFFER_SIZE];
char test[SIZE];
char* test2[SIZE];
memset(my_buffer,0,sizeof(my_buffer));
memset(test,0,sizeof(test));
memset(test2,0,sizeof(test2));
int read = fread( my_buffer, sizeof(my_buffer[0]), sizeof(my_buffer)/sizeof(my_buffer[0]), local_stream_test );
printf("FIRST READ TEST: %d\n",read);
printf("\tMY_BUFFER, SIZEOF: %lu, STRLEN: %lu\n",sizeof(my_buffer),strlen(my_buffer));
fwrite(my_buffer,sizeof(my_buffer[0]),/*strlen(aux)*/ read,local_output_test);
char* aux_test = strdup(my_buffer);
printf("\tAUX_TEST STRLEN: %lu, ## %s\n",strlen(aux_test), aux_test);
free(aux_test);
aux_test = NULL;
while(read > 0) {
if(feof(local_stream)) {
puts("BYE");
break;
}
read = fread( my_buffer, sizeof(my_buffer[0]), sizeof(my_buffer)/sizeof(my_buffer[0]), local_stream_test );
aux_test = strdup(my_buffer);
if(!aux_test) {
puts("!AUX_TEST");
break;
}
printf("READ TEST: %d\n",read);
printf("\tMY_BUFFER, SIZEOF: %lu, STRLEN: %lu\n",sizeof(my_buffer),strlen(my_buffer));
printf("\tAUX_TEST, SIZEOF: %lu, STRLEN: %lu ** SIZEOF *AUX_TEST: %lu, SIZEOF AUX_TEST[0]: %lu\n",sizeof(aux_test),strlen(aux_test),sizeof(*aux_test),sizeof(aux_test[0]));
fwrite(aux_test,sizeof(aux[0]),/*strlen(aux)*/ read,local_output_test);
printf("** AUX_TEST: %s\n",aux_test);
test2[0] = aux_test;
test2[1] = aux_test;
test2[1][3] = toupper(test2[1][3]);
fwrite(test2[1],sizeof(test2[1][0]),read,local_output_test);
printf("\n** TEST2[0] SIZEOF: %lu, STRLEN: %lu, TEST2[0]: %s\n",sizeof(test2[0]),strlen(test2[0]),test2[0]);
printf("\n** TEST2[1] SIZEOF: %lu, STRLEN: %lu, TEST2[1]: %s\n",sizeof(test2[1]),strlen(test2[1]),test2[1]);
strcpy(test2[1],aux_test);
printf("** COPIED TEST2[1]: %s\n",test2[1]);
free(aux_test);
aux_test = NULL;
puts("*******************************************");
}
return EXIT_SUCCESS;
}
入力ファイル:
converts a byte string to a floating point value
converts a byte string to an integer value
converts a byte string to an integer value
文字列を出力すると、2 回目の読み取り後に末尾に余分なジャンク値が表示されます。stdout
ファイルからの 1 回目、2 回目、3 回目の読み取りの出力は次のとおりです。
FIRST READ TEST: 5
MY_BUFFER, SIZEOF: 5, STRLEN: 5
AUX_TEST STRLEN: 5, ## conve
READ TEST: 5
MY_BUFFER, SIZEOF: 5, STRLEN: 5
AUX_TEST, SIZEOF: 4, STRLEN: 5 ** SIZEOF *AUX_TEST: 1, SIZEOF AUX_TEST[0]: 1
** AUX_TEST: rts a
** TEST2[0] SIZEOF: 4, STRLEN: 5, TEST2[0]: rts a
** TEST2[1] SIZEOF: 4, STRLEN: 5, TEST2[1]: rts a
** COPIED TEST2[1]: rts a
*******************************************
READ TEST: 5
MY_BUFFER, SIZEOF: 5, STRLEN: 13
AUX_TEST, SIZEOF: 4, STRLEN: 13 ** SIZEOF *AUX_TEST: 1, SIZEOF AUX_TEST[0]: 1
** AUX_TEST: byte▒▒▒▒
** TEST2[0] SIZEOF: 4, STRLEN: 13, TEST2[0]: byTe▒▒▒▒
** TEST2[1] SIZEOF: 4, STRLEN: 13, TEST2[1]: byTe▒▒▒▒
** COPIED TEST2[1]: byTe▒▒▒▒
私を悩ませているのは、ジャンク値が表示され始めると、文字列の長さがファイルから読み取られたバイトよりも大きくなるという事実です:13
対5
. で遊んでみましたが、一度にファイルを読み取るのに十分なサイズでない限り、BUFFER_SIZE
印刷するときに常にジャンク値を取得します。stdout
たとえば、BUFFER_SIZE
equals to500
の場合、これは の出力ですstdout
。
FIRST READ TEST: 135
MY_BUFFER, SIZEOF: 300, STRLEN: 135
AUX_TEST STRLEN: 135, ## converts a byte string to a floating point value
converts a byte string to an integer value
converts a byte string to an integer value
BYE
そして生成された出力ファイル:
BUFFER_SIZE = 5
converts arts a byte byTe stri stRing tong To a fl a FloatinoatIng poig pOint vant Value
clue
converonvErts a ts A byte bytE strinstrIng to g tO an inan IntegertegEr valu vaLue
cone
cOnvertsverTs a by a Byte stte String rinG to anto An inte inTeger vger value
aluE
BUFFER_SIZE = 500:入力ファイルと同じ。
それで、私は範囲外のメモリにアクセスしていますよね?しかしここで?この問題の原因がわかりません (C 文字列の操作方法を誤解している可能性が高いです)。
PS:
おそらく私の問題は、文字列の最後に NULL マークを追加するのを忘れたことです。やっている:
test2[0] = aux_test;
test2[0][ strlen(aux_test)+1 ] = '\0';
/* OR THIS */
test2[0][read+1] = '\0';
同じ結果になります。