|
이 건 오류가 아니고 stdio.h에 선언된 입출력함수들의 일반적인 작동방식 중 하나입니다.
text 모드인지 binary 모드인지에 따라 파일 입출력의 내용이 바뀌는 부분이 있습니다.
개행제어문자가 이에 해당합니다.
FILE를 기록용 text 모드로 열어 두고("wt","w+t" 등 t가 들어감) \r을 write하면 그냥 그대로 write하지만,
\n을 write하면 \r\n이 write됩니다.
이런 것을 원치 않으면 binary 모드로 열면 됩니다("wb","w+b" 등 b가 들어감).
모드 문자열에 t/b가 없으면 전역변수 _fmode의 값에 따르기는 하지만 보통 t가 의제됩니다.
text에서 다음줄의 처음으로 위치를 이동하려면, 다음줄로 이동(\n)후 첫열로 이동(\r)하든지 그 역으로 해야 하는데 이때 사용하는 것이 \r\n으로서 \r은 값이 0x0D \n은 값이 0x0A입니다.
그런데, 한 가지 이상한 것은 fprintf하기 직전에 fseek로 쓰고자 하는 위치로 이동시켰으므로 결과가
"00 01 02 03 04 05 06 07 08 09 0D 0B 0C 0D 0E 0F"로 나와야 하는데 그렇지 않은 것을 보면 헥사 에디터에서 파일을 읽어들일 때 개행제어문자를 자동으로 확장하는 모양입니다.
임호민 님이 쓰신 글 :
: 파일로 저장하는 프로그램 작성중 데이타가 가끔 오류를 치는 부분이 있어 다음과 같이 테스트 해 봤습니다.
: 0x00 부터 0xff 값을 파일로 저장하는 프로그램인데요...
: stdio.h는 인클루드 된 상태고, 코드는 다음과 같습니다.
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
: unsigned char temp[16];
: for(int i=0;i<16;i++)
: temp[i] = i;
:
: if(SaveDialog1->Execute()){
: FILE *stream;
: stream = fopen(SaveDialog1->FileName.c_str(), "w+");
: fseek(stream, 0, SEEK_SET);
: for(int j = 0; j < 16; j++){
: fseek(stream,j,SEEK_SET);
: fprintf(stream,"%c",(unsigned char)temp[j]);
: }
: fclose(stream);
: }
: for(int k=0;k<16;k++)
: Memo1->Lines->Text = Memo1->Lines->Text + ' ' +temp[k];
:
: }
:
: ========================================
: Memo1의 결과는 다음과 같이 제대로 나옵니다.
: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
:
: 그런데, 생성한 파일에서는 헥사 에디터로 보면 두번의 엉뚱한 데이타가 들어갑니다.
:
:
: 2byte가 더 생기네요... 0A가 들어와야 할 자리에 0D가 들어오고...
:
: 어디가 오류일까요?
:
:
: =============================================
: 약간 수정을 해 보았습니다. fwrite를 사용해 봤는데요... 결과는 1바이트가 더 생갑니다. 윈도함수인 FileWrite등을 사용해도 마찬가지 입니다.
: 결과는...
: 00 01 02 03 04 05 06 07 08 09 0D 0A 0B 0C 0D 0A 0E 0F 이고요...
: 아래는 소스코드 입니다..
:
: void __fastcall TForm1::Button1Click(TObject *Sender)
: {
: unsigned char temp[16];
: for(int i=0;i<16;i++)
: temp[i] = i;
:
: if(SaveDialog1->Execute()){
: FILE *stream;
: stream = fopen(SaveDialog1->FileName.c_str(), "w+");
: fwrite(&temp, sizeof(temp), 1, stream);
: fclose(stream);
: }
: for(int k=0;k<16;k++)
: Memo1->Lines->Text = Memo1->Lines->Text + ' ' +temp[k];
:
: }
|