[C언어] 파일입출력에서 이진모드와 텍스트모드의 차이점

gyxor의 이미지

c언어에서 stdio.h 의 파일입출력
함수에 관한 설명을 책에서 봤습니다.
예를 들어 읽기전용 mode값은 r인데 뒤에 b를 붙여주면
이진모드가 된다고 나와있습니다.
_______________________________________
#include<stdio.h>

char buffer[100] = "1234567890";
int buf = 0x4142;

int main(){
FILE *fp;

fp = fopen("test.txt","w");
fwrite(&buf,2,1,fp);
fclose(fp);
return 0;
}
_______________________________________
위 소스를 실행해보면 결과로 출력되는 파일 test.txt의 내용은
BA
가 됩니다.
fp = fopen("test.txt","wb");
이렇게 이진 모드로 변경한후 실행해봐도 결과는 같습니다.

fwrite(buffer,1,10,fp);
이렇게 문자열을 입력해봐도 "w"(텍스트모드) 와 "wb"(이진모드)
일때에 결과가
1234567890
이렇게 같습니다.

읽기의 경우에
(test.txt파일의 내용은
1234567890)
입니다.
_______________________________________
#include<stdio.h>

int buf = 0;

int main(){
FILE *fp;

fp = fopen("test.txt","r");
fread(&buf,4,1,fp);
fclose(fp);

printf("%0x",buf);
return 0;
}
_______________________________________
little endian이므로
결과는 이진모드와 텍스트모드 두 경우 모두
34333231
이렇게 나옵니다.

결과적으로 이진모드와 텍스트모드의 차이가 무엇인지 모르겠습니다.

설명부탁드립니다.

jjjjrr의 이미지

바이너리파일로 읽고쓰기를 해보시면 잘알수있을겁니다
이진모드는 기억장소에기록된내용을 그내용그대로 읽고쓰고합니다
텍스트모드는 기억장소에기록된내용이 텍스트로보고 해석해서
읽고 쓰고합니다
이진모드는 모든파일을 읽고쓰고할수있자만
텍스트모드는 바이너리파일을 읽고쓰지는못합니다
텍스트가 아니기 해석이안됩니다 그래서 글자가 깨어져나옵니다

익명 사용자의 이미지

제 man page 에는 다음과 같이 나오는군요..

The mode string can also include the letter ``b'' either as a last character or as a character between the characters in any of the two-character strings described above. This is strictly for compatibility with ANSI X3.159-1989 (``ANSI C'') and has no effect; the ``b'' is ignored on all POSIX conforming systems, including Linux. (Other systems may treat text files and binary files differently, and adding the ``b'' may be a good idea if you do I/O to a binary file and expect that your program may be ported to non-Unix environments.)

결국 b는 Linux 를 포함한 POSIX 시스템에서 효과가 없고 non-UNIX system에서 바이너리 IO를 처리 할때 b를 붙이는 것이 좋다는군요

익명 사용자의 이미지

text모드로 쓰기를 할때 \n은 \r\n으로 변환해서 씁니다.
ftp에서 asc모드나 bin모드로 업로드-다운로드 할때 발생하는 상황이 파일읽기-쓰기에서 발생합니다.

최종호의 이미지

리눅스나 유닉스 계열에서는 별 차이 없지만 도스에서는 틀려지지요.
끝과시작님이 말씀해 주신 newline 이 가장 잘보이는 차이이고,
파일의 끝을 나타내는 경우도 차이가 있습니다.

도스 텍스트파일의 경우에는 '^Z' 문자가 파일의 끝을 나타냅니다.
이에 반해서 유닉스에는 파일 끝을 나타내는 문자가 없습니다.
도스에서 파이너리 파일을 텍스트모드로 읽게되면 중간에 ^Z가 들어가는 경우,
그곳까지를 파일내용으로 인식합니다.
이런것을 이용해서 바이너리 파일 포멧을 설계할 때 앞쪽에 파일설명 비슷한 것을 넣고 ^Z 문자를 넣은 다음에 뒷쪽에 실제 데이터를 넣는 것도 가끔 쓰였지요.
예를 들면,
Pattern Recognizer 3.0 Data File^Z[바이너리 데이터.......]
를 type으로 보면 Pattern Recognizer 3.0 Data File
까지만 출력하고 프로그램이 종료하지요.

기본 파일 모드는 텍스트 모드입니다.

gyxor의 이미지

#include<stdio.h>

char buf[4] = "ab";
char inter = 26;

char ch=0;
FILE *fp;

int main(){
fp = fopen("test.txt","w");
fwrite(&buf[0],1,1,fp);
fwrite(&inter,1,1,fp);
fwrite(&buf[1],1,1,fp);
fclose(fp);

fp = fopen("test.txt","r");
while(feof(fp)==0){
ch = fgetc(fp);
printf("%d\n",ch);
}
fclose(fp);
return 0;
}

위 소스를 실행한 결과
97
-1
이었고
fp = fopen("test.txt","rb");
변경후에는
97
26
98
-1 이었습니다.
^z(0x1a) 아스키 26이 이런 역할을 하는줄 처음 알았습니다.
dos창에서 type을 해보니 역시 같은 결과 였습니다.
이진모드와 텍스트모드의 차이를 좀 알겠습니다.
단, write 할때는 이진모드나 텍스트 모드와 무관했습니다.

끝과시작 wrote:
text모드로 쓰기를 할때 \n은 \r\n으로 변환해서 씁니다.
ftp에서 asc모드나 bin모드로 업로드-다운로드 할때 발생하는 상황이 파일읽기-쓰기에서 발생합니다.

그런데 위 내용은 좀 이해가 안됩니다.

char inter = '\n';
이렇게 바꾸고 테스트를 해봐도 10과 13이 저장되지 않습니다. 단지 10만
저장이 됩니다.
어셈블리어에서 int 21로 화면에 character를 한글자씩 출력하는 경우엔
라인피드(0x0a)와 케리지리턴(0x0d) 이렇게 두개를 찍어줘야 완전한 줄바꿈이 되었습니다.
유닉스나 원도우에서는 \n(0x0a) 문자를 화면에 출력하라고 지시하면
자동으로 \r을 해주는것으로 알고있습니다.
(물론 \r을 찍으면 \r만 했습니다.)
text모드로 쓰기를 할때에 \n을 \n\r로
변환해서 쓰는것을 확인할 방법은 없을까요?
답변부탁드립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.