2011년6월30일_파일입출력시 바이너리모드와 텍스트모드에 관한 고찰
★ 책을 정독하자! ★ 바쁘다는 핑계대지 말자! ★ 열정을 가지고 열심히 자기 자신의 일을 하자! ★ 공부의 농도(집중력)을 높이자! ★ 일이 많은게 아니라 일을 하지 않으니 일이 쌓여 가는 것이다. (마인드의 문제) ★ 혼란스러운 정보의 바다 인터넷에서 사리판별 할 수 있는 자기만의 기준을 만들자! (코드는 직접 실행해 보면 되고, 나온 결과를 분석하여 검증을 하면 된다.) <내 생각> 수업시간에 얻은 데이터, 정보, 지식을 습득하여 작은 지혜를 만들고, 작은 지혜를 이용하여 다른 실험을 수행하여, 데이터를 얻는다. 얻은 데이터와 기존 데이터를 정리해 정보를 만들고, 정보를 분석하여 지식을 쌓아 간다. 부족한 데이터, 정보, 지식은 정보검색을 통하여 얻으나 상기 혼란스러운 정보의 바다(인터넷)에서 얻은 정보는 검증이 필요하다. 쌓인 지식들로 더 큰 지혜를 만들고, (말은 쉽다.) 다시 실험을 한다…(죽을 때 까지 반복) 데이터 –> 정보 –> 지식 –> 지혜 –> 데이터 –> 정보 –> 지식 –> 지혜 –> 데이터…무한 루프 왜? 이럴까? 왜 이렇게 될까? 왜 이런 결과를 얻었는가? 호기심으로 출발하여, (생각) 무엇을 어떻게 할까? //여기부터 편집………………(지적욕구) //생각 그만하고 보고서 써야해 ㅠㅠ |
고수준 파일입출력 실험 |
● 각 모드(텍스트/바이너리)에서 fscanf( )로 %c형식지정자를 사용해 하나의 문자를 a.txt파일에서 읽어오기.
1: //이진모드와 텍스트모드 파일입출력실험
2: #include <stdio.h>
3:
4: int main()
5: {
6: FILE *fp;
7:
8: char ch;
9:
10: fp = fopen("A.txt", "r");
11:
12: if(NULL == fp)
13: {
14: fprintf(stderr, "파일 열기 에러!\n");
15: return -1;
16: }
17:
18: fscanf(fp, "%c", &ch);
19: printf("%c\n", ch);
20:
21: fclose(fp);
22:
23: return 0;
24: }
10행 A.txt파일을 “r” 텍스트 파일 읽기 모드로 열고 운영체제가 관리하는(?) 그 file의 FILE구조체의 주소를 받는다.
12행 부터 16번 행까지는 예외처리로 실험과는 무관하나 나는 예외처리를 중시한다. 그래서 넣었음.
18행에서 %c형식지정자로 하나의 문자를 fp가 가리키는 FILE구조체로 부터 읽어 들여 char형 ch라는 변수에 저장을 한다.
19행에서 %c형식지정자로 ch에 저장된 하나의 문자를 터미널창(모니터)에 출력하고 다음 줄로 커서를 옮긴다.
21행 파일을 닫고 23행 프로그램을 끝낸다.
fscanf( )는 scanf( )와 같이 형식화 입력함수로 %c, %d, %s, %f와 같은 형식지정자를 사용하여,
정수/실수 <–> 문자로 변환하며 입력할 수 있다.
scanf( )가 입력받을 수 있는 장치가 표준입력(stdin)로 고정되어 있는 것과 달리 fscanf( )는 장치를 바꿀 수 있다.(정할 수 있다.)
즉, 정수/실수 <-> 문자 변환함수와 입력함수가 결합되어 문자열처리를 따로 할 필요없어 조금 편리하게 입력할 수 있는 함수이다.
(리눅스 터미널창과 윈도우 도스창은 모두 문자만 취급한다.)
10행 “r”로 하여 텍스트모드로 읽는 것과 “rb”로 하여 이진모드로 읽는 것은 차이가 없다.
<실행결과>
[스크린샷] 텍스트모드 읽기 [스크린샷] 바이너리모드 읽기
그럼 왜? 모드에 따른 차이를 보이지 않는 것일까?
%c형식지정자…이 실험에서 리눅스와 윈도우 운영체제에 따른 차이는 없었다.
//생략… ㅠㅠ
● 각 모드(텍스트/바이너리)에서 fprintf( )로 %d형식지정자를 사용하여 정수데이터를 파일에 기록하기
1: //이진모드와 텍스트모드 파일입출력실험2
2: #include <stdio.h>
3:
4: int main()
5: {
6: FILE *fp;
7: int iNum = 0x12345678;
8: int iRet;
9:
10: fp = fopen("A.txt", "w");
11:
12: if(NULL == fp)
13: {
14: fprintf(stderr, "파일 열기 에러!\n");
15: return -1;
16: }
17:
18: iRet = fprintf(fp, "%d\n", iNum);
19:
20: fclose(fp);
21:
22: return 0;
23: }
달라진 점…
7행에서 int형 iNum을 선언하고 0x12345678을 대입한다. (주의! 16진수)
10행에서 파일을 텍스트 쓰기모드로 열고 운영체제가 관리하는 그 file의 FILE구조체의 주소를 받는다.
18형에서 iNum의 값을 10진수로 바꾸어 문자열로 변환한 값을 fp가 가리키는 FILE구조체를 통해 그 file에 기록하고,
기록한 문자의 수를 반환하여 iRet에 저장한다.
fprintf( )는 printf( )와 같이 형식화 출력함수로 %c, %d, %s, %f와 같은 형식지정자를 사용하여,
정수/실수 <–> 문자로 변환하며 출력할 수 있다.
printf( )가 입력받을 수 있는 장치가 표준출력(stdout)로 고정되어 있는 것과 달리 fprintf( )는 장치를 바꿀 수 있다.(정할 수 있다.)
즉, 정수/실수 <-> 문자 변환함수와 출력함수가 결합되어 문자열처리를 따로 할 필요없어 조금 편리하게 출력할 수 있는 함수이다.
10행 “w”로 하여 텍스트모드로 쓰는 것과 “wb”로 하여 이진모드로 쓰는 것은 차이가 없다.
<실행결과>
[스크린샷] 텍스트모드 쓰기 [스크린샷] 바이너리모드 쓰기
파일입력과 마찬가지로 출력도 파일열기모드에 따른 차이가 없다.
왜 그런 것일까?
여기 잠깐 실험이 잘 못 되었다. HexaView로 파일을 열어 봐야 한다.
cat명령으로 읽어도 되긴하나 개행문자가 없으면 화면에 출력이 되지 않는다.
[스크린샷] HexaView로 파일의 바이너리값과 ASCII값 확인
HexaView로 열어 보니..
텍스트모드와 바이너리모드 모두 상기의 스크린샷과 같이 결과….
7월4일 추가…
여기서부터 편집해야 되고,
실험의 방향과 순서를 먼저 정하고 행한 뒤에 얻은 데이터를 분석하여 결론을 내리자.
winhex프로그램으로 드라이브를 열어 txt파일을 보니 텍스트데이터와 \r\n \t등의 제어문자만 있고,
리눅스에서 짠 소스인지 윈도우에서 짠 소스인지 구분할 다른 방법이 없었다. (\r\n, \n뿐)
리눅스에서 짠 텍스트파일(소스코드)는 개행문자로 \n만 사용하므로 윈도우 메모장에서 열면 깨져나온다.
윈도우용이더라도 워드패드같은 경우엔 깨지지 않는데 어떻게 구분하는 것일까?