11 장입출력과운영체제 0
printf() 특징 - 임의의개수의인자출력 - 간단한변환명세나형식을사용한출력제어 11-1
printf() printf(control_string, other_argument) - 예 printf("she sells %d %s for $%f", 99, "sea shells", 3.77); control_string: "she sells %d %s for $%f" other_arguments: 99, "sea shells", 3.77 - 변환명세는 % 로시작하여변환문자로끝남 11-2
printf() 변환문자 printf() 변환문자 대응되는인자의출력형태 c 문자 d,i 10진정수 u 부호없는 10진정수 o 부호없는 8진정수 x, X 부호없는 16진정수 e 부동소수점수 ; 예 : 7.123000e+00 E 부동소수점수 ; 예 : 7.123000E+00 f 부동소수점수 ; 예 : 7.123000 g e형식과 f 형식중짧은쪽 G E형식과 f 형식중짧은쪽 s 문자열 p 대응되는인자가 void 포인터임 ; 그값이 16진수형태로출력됨 n 대응되는인자는정수형포인터로서그값은현재까지출력된문자의개수임 ; 인자는변환되지않음 % %% 의형식으로 % 를출력스트림에씀 ; 대응되는인자는없음. 11-3
printf() 예제 printf("she sells %d %s for $%f", 99, "sea shells", 3.77); 변환형식 %d %s %f 대응되는인자 99 "sea shells" 3.77 11-4
printf() % 와변환문자사이에올수있는것들 - 플래그문자들 - 빼기기호 - 더하기기호 - 공백 - # 기호 - 0 - 필드폭 - 정밀도 - h 또는 l - L 11-5
printf() 선언과초기화 char c = 'A', s[] = "Blue moon!"; 변환형식대응되는인자필드내에서출력형태비고 %c c "A" 필드폭 1 ( 디폴트 ) %2c c " A" 필드폭 2, 우측정렬 %-3c c "A " 필드폭 3, 좌측정렬 %s s "Blue moon!" 필드폭 10 ( 디폴트 ) %3s s "Blue moon!" 공간이더필요함 %.6s s "Blue m" 정밀도 6 %-11.8s s "Blue moo " 정밀도 8, 좌측정렬 11-6
printf() 선언과초기화 int i = 123; double x = 0.123456789; 변환형식대응되는인자필드내에서출력형태 비고 %d i "123" 필드폭 3 ( 디폴트 ) %05d i "00123" 영으로채움 %7o i " 173" 우측정렬, 8진수 %-9x i "7b " 좌측정렬, 16진수 %-#9x i "0x7b " 좌측정렬, 16진수 %10.5f x " 0.12346" 필드폭 10, 정밀도 5 %-12.5e x "1.23457-01 " 좌측정렬, e-형식 11-7
scanf() scanf(control_string, other_argument) - 예 char a, b, c, s[100]; int n; double x; scanf("%c%c%c%d%s%lf", &a,&b,&c,&n,s,&x); - control_string: "%c%c%c%d%s%lf" - other_arguments: &a, &b, &n, s, &x 11-8
scanf() scanf( ) 변환문자 변환문자 입력스트림에서대응되는문자 대응인자의포인터형 c 공백을포함한모든문자 char d, i 10 진정수 ( 부호는옵션 ) integer u 10 진정수 ( 부호는옵션 ) unsigned integer o 8 진수 ( 부호는옵션 ) unsigned integer x, X 16 진수 ( 부호는옵션 ) unsigned integer e, E, f, g, G 실수 ( 부호는옵션 ) floating type s 공백없는문자열 Char p printf() 함수의 %p에의해출력되는 void * 것으로일반적으로부호없는 16진정수임 n, %, [...] 다음표참조 11-9
scanf() scanf( ) 변환문자변환문자설명입력스트림의문자와짝을이루지않는다. 대응되는인자는정수 n 형포인터로서, 지금까지읽어들인문자의개수를저장한다. % 입력스트림에서하나의 % 와짝을이룬다. 대응되는인자는없다. [...] 각괄호 [ ] 안에있는문자들을스캔집합이라한다. 이것은무엇이짝을이루는가를결정한다. ( 아래설명을참조하여라.) 대응되는인자는문자배열의기본주소에대한포인터이고, 이배열은끝에자동적으로추가되는널문자를포함하여대응되는모든문자들을포함할만큼큰크기를가져야한다. 11-10
scanf() 제어문자열은다음과같은것을포함할수있음 - 여백 - % 이외의공백문자가아닌일반문자 - % 로시작해서변환문자로끝나는변환명세 - h - l - L 11-11
int i; char c; char string[15]; scanf() 예제 scanf("%d, %*s %% %c %5s %s", &i, &c, string, &string[5]); * 입력스트림 : 45, ignore_this % C read_in_this** - i : 45 - c : C - string[0-5] : "read_" - string[5-14] : "in_this**" - scanf() 는 4 를리턴 11-12
fprintf()/fscanf() 각각 printf() 와 scanf() 함수의파일버전 함수원형 int fprintf(file *fp, const char *format, ) int fscanf(file *fp, const char *format, ) fprintf(stdout,...); 와 printf(...); 는같은의미 fscanf(stdin,...); 은 scanf(...); 와같은의미 11-13
sprintf()/sscanf() 각각 printf() 와 scanf() 함수의문자열버전 함수원형 int sprintf(char *, const char *,...); int sscanf(const char *, const char *,...); 11-14
fopen() fopen(filename, mode) 형태의함수호출은 filename 파일을 mode에지정된모드로열고, 파일포인터를리턴함 11-15
fopen() 모드 모드 "r" "w" "a" "rb" "wb" "ab" 의미읽기위해문서파일열기쓰기위해문서파일열기첨부하기위해문서파일열기읽기위해이진파일열기쓰기위해이진파일열기첨부하기위해이진파일열기 - 모드뒤의 + 는파일을읽기와쓰기로모두연다는것을의미함 11-16
fopen()/fclose() 파일열기와닫기의전형적인예제코드 #include <stdio.h> int main(void){ int a, sum = 0; FILE *ifp, *ofp; ifp = fopen("my_file", "r"); ofp = fopen("outfile", "w");... fclose(ifp); fclose(ofp); } 11-17
ftell(file_ptr) 파일의임의의위치접근 - 파일위치지시자의현재값을리턴 fseek(file_ptr, offset, place) - 파일위치지시자를 place부터 offset 바이트떨어진곳을나타내는값으로설정함 - place의값은 0(SEEK_SET), 1(SEEK_CUR), 2(SEEK_END) 중하나가될수있는데, 이것들은각각파일의처음, 현재위치, 파일의끝을나타냄 11-18
파일의임의의위치접근 파일을역으로출력하는프로그램 #include <stdio.h> int main(void){ char fname[100]; int c; FILE *ifp; fprintf(stderr, "\ninput a filename: "); scanf("%s", fname); ifp = fopen(fname, "rb"); fseek(ifp, 0, SEEK_END); fseek(ifp, -1, SEEK_CUR); while (ftell(ifp) > 0) { c = getc(ifp); putchar(c); fseek(ifp, -2, SEEK_CUR) ; } return 0; } 11-19
파일기술자입출력 파일기술자 : 파일과연관된음이아닌정수 프로그램실행시자동으로열리는파일및기술자 파일명 연관된파일기술자 표준입력 0 표준출력 1 표준에러 2 11-20
파일기술자입출력 전형적인예제 int main(void){ char mybuf[100], *p; int in_fd, out_fd; in_fd = open("my_file", O_RDONLY); out_fd = open("outfile", O_WRONLY, 0600);... n = read(in_fd, mybuf, 100); write(out_fd, mybuf, n);... close(in_fd); close(out_fd); } 11-21
파일접근허가 UNIX/LINUX 파일에는사용자별접근허가가있음 사용자종류 : 소유자 (u), 그룹 (g), 다른사용자 (o) 접근종류 : 읽기 (r), 쓰기 (w), 실행 (x) 사용자별접근종류설정함 (9 bit) 예 (ls l의결과 ) -rwxr--r-- 1 kmh prof 57 10 월 20 13:04 im.c 11-22
파일접근허가 연상기호및 8 진수 연상기호 2진표현 8진표현 r-- 100 04 -w- 010 02 --x 001 01 rw- 110 06 r-x 101 05 -wx 011 03 rwx 111 07 11-23
파일접근허가의예 파일접근허가 연상기호 8진표현 rw------- 0600 rw----r-- 0604 rwxr-xr-x 0755 rwxrwxrwx 0777 11-24
파일접근허가 open() 함수의 3 번째인자에파일접근허가명시 out_fd = open("outfile", O_WRONLY, 0600); UNIX/LINUX에서파일접근허가병경방법 $ chmod 666 file $ chmod a+w file $ chmod o-w file 11-25
C 프로그램에서명령어실행 system() 함수를사용하면프로그램에서운영체제명령어를실행할수있음 프로그램내에서명령어라인으로부터입력된파일을 vi를사용하여편집하는코드 char command[maxstring]; sprintf(command, "vi %s", argv[1]); printf("vi on the file %s is coming up...", argv[1]); system(command); 11-26
popen() 을통한프로세스생성 popen() : 파이프를생성하고프로세스를생성하여이파이프를통해통신할수있게함 pclose() 를사용하여닫음 예제 FILE *ifp; int c; ifp = popen( ls, r );... c = getc(ifp);... pclose(ifp); 11-27
환경변수출력프로그램 환경변수 #include <stdio.h> int main(int argc, char *argv[], char *env[]){ int i; for (i = 0; env[i]!= NULL; ++i) printf("%s\n", env[i]); return 0; } 11-28
컴파일러옵션 cc/gcc 옵션 컴파일러에유용한옵션들 -c 컴파일만수행함, 대응되는.o 파일생성 -g 디버거를사용할수있는코드생성 -o name name에실행가능한코드를출력 -p 프로파일러를사용할수있는코드생성 -v 많은정보를생성 -Dname=def.c 파일상단에 #define name def 행을삽입 -E 전처리기만호출 -Idir dir 디렉토리에서 #include 파일들을찾음 -M makefile 생성 -O 코드최적화수행 -S 대응되는.s 파일에어셈블러코드생성 11-29
프로파일러 UNIX에서 cc에 -p 옵션을사용하면컴파일러로하여금각루틴이호출된횟수를알려주는코드를생성하게함 이렇게생성된코드는라이브러리함수인 monitor() 를자동으로호출하고 mon.out 파일을생성함 prof 명령을사용하면 mon.out 파일을사용하여실행프로파일을생성함 11-30
프로파일러사용예 $ cc -p -o quicksort main.c quicksort.c $ quicksort $ prof quicksort 11-31
prof 출력 $ prof quicksort % time cumsecs #call ms/call name 46.9 7.18 9931 0.72 _partition 16.1 9.64 1 2460.8 _main 11.7 11.43 19863 0.09 _find_pivot 10.8 13.08 mcount 6.9 14.13 50000 0.02 _rand 6.4 15.12 19863 0.05 _quicksort 1.4 15.33 _monstartup 0.0 15.33 1 0.00 _gettimeofday 0.0 15.33 1 0.00 _profil 0.0 15.33 1 0.00 _srand 0.0 15.33 1 0.00 _time 11-32
라이브러리 ar : 라이브러리아카이브를생성, 변경, 추출하는명령 라이브러리에있는파일보기예 $ ar t /lib/libc.a 라이브러리생성 $ ar rug file.a file1.o file2.o... $ ranlib file.a 컴파일 $ cc main.c file.a 11-33
시간측정 헤더파일 time.h에함수원형이정의된함수들을사용하여컴퓨터클록을접근할수있음 clock() : 프로그램이사용한시간에대한시스템의최대근사치리턴 time() : 1970년 1월 1일부터경과된시간을초단위로환산하여리턴 11-34
make 대형프로그램을한파일에저장하는것은매우비효율적이고많은비용이소요됨 이러한대형프로그램은여러개의.c 파일로나누어작성하고필요에따라개별적으로컴파일하는것이훨씬효율적임 make의필요성 make 유틸리티는원시파일을관리하고라이브러리와그에관련된헤더파일을편리하게접근하도록하는데사용됨 make는 makefile이라는파일을읽고, 종속관계트리를만들어필요한동작을수행함 11-35
makefile makefile 은종속관계와동작을명시하는규칙이라고하는목록들로구성됨 각규칙의형식 예 file_1 file_2 : source_file_1 source_file_2 <tab>command all: main.o sort.o cc -o sort main.o sort.o main.o: main.c sum.h cc -c main.c 11-36
make 예제 예제 - main.c, sum.c, sum.h 로구성된프로그램 sum: main.o sum.o cc -o sum main.o sum.o main.o: main.c sum.h cc -c main.c sum.o: sum.c sum.h cc -c sum.c - make rule_label 수행 (rule_label 이없으면 makefile 의첫번째규칙을수행함 ) 11-37
종속트리 sum main.o sum.o main.c sum.h sum.c sum.h 11-38
makefile 예제 예제 2 sum: main.o sum.o cc -o sum main.o sum.o main.o: sum.h cc -c main.c sum.o: sum.h cc -c sum.c 예제 3 sum: main.o sum.o cc -o sum main.o sum.o main.o sum.o: sum.h cc -c $*.c 11-39
파일에새로운시간설정 touch make 는파일시간을보고동작할것인지결정 다시전체를컴파일하고싶을때 touch 를수행후 make 함 예 $ touch *.c $ make 11-40