C언어 - text mode, binary mode, fprintf, freed, 배열과 포인터
- 텍스트 모드와 이진모드(Text Mode and Binary Mode)
⇒ 텍스트 형식과 이진 형식은 숫자를 저장하는 방법의 구분이고, 텍스트 모드와 이진 모드는 도스 파일의 해석에 대한 구분이다. 텍스트 모드와 이진 모드의 차이는 유닉스에서 유래된 C 언어와 도스 운영체제의 차이점에서 비롯되었다. 텍스트 모드는 도스 파일을 유닉스 파일처럼 보이기 위해서 개행문자와 파일의 끝을 C언어가 변환시킨다. 이진 모드에서는 도스 파일을 변환없이 그대로 보인다.
// 파일을 이진 모드로 열어서, 한 문자씩 읽어 화면에 출력하는 프로그램
#include<stdio.h>
#define LENGTH 10
int main(int argc, char *argv[])
{
int i = 0;
FILE *fp;
char ch;
char string[LENGTH+1];
if(argc !=2)
{
printf("Wrong in command line");
return -100;
}
if((fp=fopen(argv[1], "rb")) == NULL)
{
printf("Can't open file %s.", argv[1]);
return -10;
}
while((ch = fgetc(fp)) != EOF)
{
printf("%3x", ch);
if(ch>31)
{
*(string + i++) = ch;
}
else
{
*(string + i++) = '.';
}
if(i>=LENGTH)
{
*(string + i) = '\0';
printf(" %s\n", string);
i=0;
}
}
fclose(fp);
return 0;
}
⇒ 실행결과
/* 학생의 이름, 영어와 수학성적을 입력받아 평균을 계산하여 파일에 기록하고, 파일의 내용을 출력하는 프로그램 */
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[25];
int english;
int math;
float average;
}STUDENT;
int main()
{
STUDENT st;
FILE *fp;
if((fp = fopen("d11-7.dat","wb")) == NULL)
{
printf("Can't open file d11-7.dat");
return -100;
}
printf("Please type <enter key> for Name, if you finish input\n");
printf("Enter Name: ");
gets(st.name);
while(strlen(st.name)>0)
{
printf("Enter English score: ");
scanf("%d", &st.english);
printf("Enter Math score: ");
scanf("%d", &st.math);
st.average = ((float)st.english + st.math)/2;
fwrite(&st, sizeof(st), 1, fp);
if(ferror(fp))
{
perror("Error: ");
fclose(fp);
return -100;
}
printf("\nPlease type <enter key> for Name, if you finish input\n");
printf("Enter Name: ");
//fflush(stdin);
getchar(); // while(getchar()!='\n');
gets(st.name);
}
fclose(fp);
if((fp = fopen ("d11-7.dat", "rb")) == NULL)
{
printf("Can't open file d11-7.dat");
return -10;
}
printf("\nName english math Average\n");
while(fread(&st, sizeof(st), 1, fp)==1)
{
printf("%s\t %d\t %d\t %7.2f\n", st.name, st.english, st.math, st.average);
}
fclose(fp);
return 0;
}
// 데이터 파일의 두 번째 줄을 화면과 파일에 출력하는 프로그램
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
char ch = 0;
long pos;
FILE *infp, *outfp;
if(argc != 3)
{
printf("Data file name missing!");
return -100;
}
if((infp = fopen(argv[1], "rb")) == NULL)
{
printf("cannot fileopen");
return -10;
}
if((outfp = fopen(argv[2], "wb")) == NULL)
{
printf("cannot file create");
return -1;
}
while(fgetc(infp) != '\n');
pos = ftell(infp);
while(ch !='\n')
{
fseek(infp, pos++, SEEK_SET);
ch = fgetc(infp);
putchar(ch);
fputc(ch, outfp);
}
fclose(infp);
fclose(outfp);
return 0;
}
⇒ 실행결과
#include<stdio.h>
int main()
{
FILE *fp;
int iNum = 0x12345678;
int iRet;
fp = fopen("A.txt","w");
if(fp==NULL)
{
printf("File read error\n");
return -100;
}
iRet = fprintf(fp, "%d\n", iNum); // fprintf로 iNum 출력
iRet = fwrite(&iNum, 1, 4, fp); // fwrite로 iNum 출력
fprintf(fp, "%d\n", iNum);
close(fp);
return 0;
}
⇒ A. txt파일을 열어보면 → 305419896이 저장되어 있는 것을 볼 수 있다.
⇒ 왼쪽의 코드를 보면 각 숫자에 해당하는 ASCII 코드번호가 16진수로 나타나는데 이것으로 보아 int형 4byte로 저장된 것이 아니라 각각의 숫자가 char형 1byte로 저장된 것을 볼 수 있다. 이것은 fprintf와 fscanf를 사용했을 때, 우리가 입력할 데이터가 4바이트 값에 들어가지 않고 그 크기가 커졌음을 알 수 있다.
⇒ fprintf, fscanf는 화면출력 기반, 즉 화면에 표시된 것을 저장하므로 데이터를 살펴보았을 때 그 값이 다르다.
⇒ 이것을 바꾸기 위해 아스키 xV4에 해당하는 것을 보면 78 56 34 12 의 결과를 볼 수 있으며 이를 위해 fread, fwrite를 사용하였다.
- 배열
char T[] = "ABCDE";
65 |
66 |
67 |
68 |
69 |
00 |
⇒ 위 배열의 symbol table은
type |
name |
address |
char[] |
T |
100 |
이며 char[] 는 char * const T와 같으며 char *P = T로 했을 때 양 쪽의 형은 일치한다.
// 배열과 포인터의 관계를 알기위한 테스트
#include<stdio.h>
int main()
{
char T[] = "ABCDE";
char *P = T;
printf("%s\n", T);
T[0] = 'Z';
printf("%s\n", T);
*(P+0) = 'A';
printf("%s\n", T);
T[1] = 'Z';
printf("%s\n", T);
*(P+1) = 'B';
printf("%s\n", T);
*(T+2) = 'Z';
printf("%s\n", T);
P[2] = 'C';
printf("%s\n", T);
return 0;
}
⇒ *P = 'A'; 는 *(P+0)='A'와 같다.
⇒ *(P+1)의 주소를 알기위해 &를 붙이면
→ &*(P+1) → (P+1) → &P[1]로 되며 이 세가지는 모두 같다.
※ 포인터란 가리키는 메모리를 어떻게 볼것인가? 라고 생각해 볼 수 있다.
(해당하는 곳을 몇바이트 덩어리로 볼것인가.)
'내장형 하드웨어 > C언어' 카테고리의 다른 글
C언어 - 함수 포인터, 다중 포인터, 구조체 (0) | 2011.07.05 |
---|---|
C언어 - 배열의 값과 주소 표시법, 함수 포인터 배열 (0) | 2011.07.04 |
C언어 - 저수준 입출력, 리다이렉션 (0) | 2011.06.30 |
저수준 입출력, HEXAVIEW (2) | 2011.06.28 |
tcp/ip 기초, 저수준 입출력 (0) | 2011.06.28 |