처음부터 차근차근
Unix 기본 시스템 함수 - getopt(), time(), localtime(), localtime_r(), ftime(), gettimeofday(), mktime(), 파일 기술자, bcopy() 본문
Unix 기본 시스템 함수 - getopt(), time(), localtime(), localtime_r(), ftime(), gettimeofday(), mktime(), 파일 기술자, bcopy()
_soyoung 2022. 4. 15. 17:18getopt()
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <stdlib.h>
#include <string.h> // string 헤더
#include <unistd.h> // unix 계열 헤더
// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]) {
// 옵션 넣을 변수 생성
int nOpt;
printf("Original\n");
// 파일 실행할 때 입력한 매개변수들 모두 출력
for (int i = 0; i < argc; i++) {
printf("value[%d] : %s\n", i, argv[i]);
}
printf("--------Options-------\n");
// getopt() : 옵션을 찾아내는 함수
while ((nOpt = getopt(argc, argv, "abc")) != -1) {
// 옵션을 찾아내서 출력한다.
printf("Option : %c\n", nOpt);
}
return 0;
}
명령어, 파라미터, 사용된 옵션들이 출력되었다.
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <stdlib.h>
#include <string.h> // string 헤더
#include <unistd.h> // unix 계열 헤더
// argc : 명령 파라미터의 개수(자기 자신까지 1개로 침)
// argv[] : 각각의 아규멘트의 값들(argv[0]는 자기자신)
int main(int argc, char* argv[]) {
// 옵션 넣을 변수 생성
int nOpt;
// 옵션과 다음에 넣은 값을 출력한다.
// optarg : 옵션 다음에 입력한 값
while ((nOpt = getopt(argc, argv, "s:d:h")) != -1) {
switch (nOpt) {
// 옵션이 s면
case 's' :
printf("s : %s\n", optarg);
break;
// 옵션이 d면
case 'd':
printf("d : %s\n", optarg);
break;
// 옵션이 h나 다른 옵션을 넣으면
case 'h':
default:
printf("Usage : %s [-s value] [-d value] value\n",
argv[0]);
// 종료
return -1;
}
}
// 옵션 값에 해당되지 않는 파라미터 값을 출력
// optind : 옵션의 인덱스
// 옵션 값 아닌 파라미터 값을 뒤가 아닌 앞에 붙여도 상관없다. getopt() 함수가 다시 정렬해주기 때문
for (; optind < argc; optind++) {
// 인덱스는 5부터 시작함
printf("value[%d] : %s\n", optind, argv[optind]);
}
return 0;
}
s 옵션 값으로 aa가 입력되었고, d옵션 값으로 bb가 입력되었다는 것이 출력되었다.
그리고 옵션 값에 해당하지 않는 파라미터 cc, dd가 출력되었다.
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <unistd.h> // unix 계열 헤더
int main(void) {
// time 변수
time_t timeCurrent = 0;
// 10번 반복
// 현재의 시간을 출력한다.
for (int i = 0; i < 10; i++) {
// time() : 현재 시각을 1970년 1월 1일을 기준으로 초 단위 값 추출
timeCurrent = time(NULL);
printf("Current time is %d\n", timeCurrent);
sleep(1);
}
return 0;
}
현재 시간이 1초 간격으로 10번 출력되었다.
localtime()
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <unistd.h> // unix 계열 헤더
#include "print_localtime.h" // print_localtime 헤더 include
int main(void) {
// time 변수
time_t timeCurrent;
// 연월일 넣을 변수
struct tm* tmCurrent;
// 현재 시간 뽑기
time(&timeCurrent);
// 뽑은 현재 시간 출력
printf("Current Time : %d\n", timeCurrent);
// 우리가 알아볼 수 있게 변환(연 월 일)
tmCurrent = localtime(&timeCurrent);
print_localtime(*tmCurrent);
return 0;
}
현재 시간이 초 단위로 출력되었고,
초 단위로 출력된 시간이 다시 연,월,일로 변환되어 출력되었다.
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <unistd.h> // unix 계열 헤더
#include "print_localtime.h" // print_localtime 헤더 include
int main(void) {
// time 변수
time_t timeCurrent;
// 연월일 넣을 변수
struct tm* tm1;
struct tm* tm2;
// 현재 시간 뽑기
time(&timeCurrent);
// 연 월 일로 변환
tm1 = localtime(&timeCurrent);
// 1초 쉬기
sleep(1);
// 현재 시간 뽑기
time(&timeCurrent);
// 연 월 일로 변환
tm2 = localtime(&timeCurrent);
// 출력
print_localtime(*tm1);
print_localtime(*tm1);
return 0;
}
localtime() 함수는 static처럼 정적으로 선언되어 있어서 원래 1초 뒤의 시간을 출력해야 되는데 그렇지 않은 게 결과로 보인다.
localtime_r()
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <unistd.h> // unix 계열 헤더
#include "print_localtime.h" // print_localtime 헤더 include
int main(void) {
// time 변수
time_t timeCurrent;
struct tm tm1;
struct tm tm2;
// 현재 시간 뽑기
time(&timeCurrent);
// 연 월 일로 변환
localtime_r(&timeCurrent, &tm1);
// 1초 쉬기
sleep(1);
// 현재 시간 뽑기
time(&timeCurrent);
// 연 월 일로 변환
localtime_r(&timeCurrent, &tm2);
// 출력
print_localtime(tm1);
print_localtime(tm2);
return 0;
}
Localtime() 함수와 다르게 1초가 지나면 1초 지난 시간으로 출력된다.
두번째 인자에 변환 결과를 기록하기 때문에 값이 변한 상태로 출력되는 것이다.
ftime()
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <sys/timeb.h> // timeb 사용할 때 필요한 함수
#include <unistd.h> // unix 계열 헤더
int main(void) {
// time 변수
struct tm tmCurrent;
struct timeb tmb;
// 현재 시간 뽑기
time(&tmb);
// 연 월 일로 변환
localtime_r(&(tmb.time), &tmCurrent);
// 현재 time 출력
printf("Current : %04d/%02d/%02d %02d:%02d:%02d\n",
tmCurrent.tm_year + 1900,
tmCurrent.tm_mon + 1,
tmCurrent.tm_mday,
tmCurrent.tm_hour,
tmCurrent.tm_min,
tmCurrent.tm_sec,
tmb.millitm
);
return 0;
}
초가 지날 때마다 시간이 변하는 것을 볼 수 있다.
gettimeofday()
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <sys/time.h>
#include <unistd.h> // unix 계열 헤더
int main(void) {
struct timeval tv;
struct tm tmCurrent;
// gettimeofday() : 현재 시각을 마이크로초 단위의 값으로 추출하는 함수
gettimeofday(&tv, NULL);
// 연 월 일로 변환
localtime_r(&(tv.tv_sec), &tmCurrent);
// 현재 time 출력
printf("Current : %04d/%02d/%02d %02d:%02d:%02d.%06d\n",
tmCurrent.tm_year + 1900,
tmCurrent.tm_mon + 1,
tmCurrent.tm_mday,
tmCurrent.tm_hour,
tmCurrent.tm_min,
tmCurrent.tm_sec,
tv.tv_usec
);
return 0;
}
gettimeofday() 함수에 의하여 시간이 초까지 더 세밀하게 출력된 것을 볼 수 있다.
mktime()
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <time.h> // time() 함수 헤더
#include <sys/time.h>
#include <unistd.h> // unix 계열 헤더
int main(void) {
// time 구조체와 변수
struct tm tm1;
time_t timeCurrent = 0;
// 값 설정
tm1.tm_year = 2021 - 1900;
tm1.tm_mon = 4 - 1;
tm1.tm_mday = 14;
tm1.tm_hour = 20;
tm1.tm_min = 30;
tm1.tm_sec = 5;
tm1.tm_isdst = -1;
// mktime() : struct tm 형태의 시각정보를 초 단위의 UNIX 시간 정보로 변환하는 함수
timeCurrent = mktime(&tm1);
// mktime() 함수 결과 값이 실패이면
if (timeCurrent == -1) {
printf("-unknown-\n");
}
// 성공하면
else {
printf("Seconds: %ld\n", timeCurrent);
}
return 0;
}
초 단위의 UNIX 시간 정보로 변환해서 출력한 것을 볼 수 있다.
파일기술자
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <unistd.h> // unix 계열 헤더
#include <sys/stat.h> // 파일 작업할 때 필요한 헤더
#include <sys/types.h> // 파일 작업할 때 필요한 헤더
#include <fcntl.h> // 파일 작업할 때 필요한 헤더
#include <string.h> // string 헤더
#include <stdlib.h> // random() 사용하기 위한 헤더
#include <time.h> // time() 사용하기 위한 헤더
#define MAX_FD 16 // 상수 정의
int main(void) {
int fd[MAX_FD];
int fdCnt;
int i;
int nRandom;
char buffer[BUFSIZ]; // 버퍼
time_t currentTime; // time 변수
// 메모리 세팅 함수
// fd : 세팅하고자하는 메모리의 시작주소
// 0 : 메모리에 세팅할 값
// sizeof(fd) : 세팅할 크기(byte 단위)
memset(fd, 0, sizeof(fd));
// 현재 시각 초 단위 값으로 추출(1970.01.01 기준)
currentTime = time(NULL);
// 난수를 발생시키는 seed 값을 재설정해주는 함수
srandom((unsigned int)currentTime);
// (난수 + 1) % 16
nRandom = (random() + 1) % MAX_FD;
for (fdCnt = 0; fdCnt < nRandom; fdCnt++) {
// buffer : 출력값 저장할 버퍼, "./test%d.txt" : 서식 문자열, fdCnt : 서식 연산자에 치환할 값
sprintf(buffer, "./test%d.txt", fdCnt);
// 버퍼 안에 들어간 경로의 파일을 읽기 전용으로 열되, 없으면 새로만든다.(소유자 : 읽기/쓰기(6), 나머지 : 읽기(4) 권한으로)
fd[fdCnt] = open(buffer, O_CREAT|O_RDONLY, 0644);
}
// 프로세스 아이디 구해서 출력
printf("Process_Number : %d\n", getpid());
printf("The number of FDs is %d\n", fdCnt);
getchar(); // 키보드 한 개를 입력받음
// 16번 반복하여 fd(open한 파일들)를 모두 close
for (i = 0; i < MAX_FD; i++) {
if (fd[i] > 0) {
close(fd[i]);
}
}
for (i = 0; i < fdCnt; i++) {
// sprintf로 파일 경로 세팅
sprintf(buffer, "./test%d.txt", i);
// 파일 삭제
unlink(buffer);
}
return 0;
}
실행결과
실행시켰더니 프로세스 아이디와 만들어진 파일의 개수가 출력되고,
현재 경로에 test~.txt 파일들이 생긴 것을 볼 수 있다.
그 다음 enter을 쳤더니(getchar()로 인해 키보드 한 개 입력받음) 만들어졌던 파일들이 다 삭제되었다.
bcopy()
바이트 배열 처리 함수
#include <stdio.h> // c 언어 파일 작성할 때 필요한 헤더
#include <string.h> // string 헤더
#include <strings.h> // strings 헤더
int main(void) {
// 20 크기의 배열 정의(안의 값은 모두 0으로 초기화)
char p_strText1[20] = { 0, };
char p_strText2[20] = { 0, };
for (int i = 0; i < 20; i++) {
// p_strText1 배열 안에 'a' + i 값 넣음
p_strText1[i] = 'a' + i; // abcde....
}
// 각각의 배열에 어떤 값이 들어가 있는지 출력
printf("Text1 : %s\n", p_strText1); // 아까 넣은 abcd... 가 나옴
printf("Text2 : %s\n", p_strText2); // 아직 아무 값도 없음
printf("Calling bcopy().\n");
// p_strText1를 p_strText2에다 복사(20 byte 복사)
bcopy(p_strText1, p_strText2, 20);
// 각각의 배열에 어떤 값이 들어가 있는지 출력
printf("Text1 : %s\n", p_strText1); // abcd...
printf("Text2 : %s\n", p_strText2); // abcd...
return 0;
}
Text1 내용이 복사되어 Text2에도 똑같이 출력된다.
출처 : 네트워크개론(22-1학기)김병국교수 강의 내용 변형 및 요약
'Linux & Unix' 카테고리의 다른 글
tcp 소켓 생성과 TCP 클라이언트용 API (2) | 2022.05.22 |
---|---|
바이트 순서 변환과 호스트 정보 송수신 관련 함수들 (1) | 2022.05.14 |
파일 접근과 해제, 읽기, 쓰기, 접근 위치 이동, 생성, 삭제 (0) | 2022.04.07 |
Virtual Box 공유 폴더 만들기, 명령어 정리 (0) | 2022.04.06 |
라이브러리와 아카이브, 에러 처리 (0) | 2022.03.01 |