시간 관련 함수

프로그램에서 시간은 거의 필수로 다루어질 만큼 중요한 요소입니다. 그래서 우리는 시간을 잘 다루어야 할 필요가 있습니다.  그래서 이번에는 C언어에서 시간과 관련된 함수 몇가지를 살표보도록 하지요. 지금부터 다룰 함수는 모두 시간과 관련된 함수이므로 time.h 헤더파일을 포함시켜야한다는 것을 잊지 마세요.

time

가장 기본적인 시간 관련 함수입니다. 함수의 원형은 다음과 같죠.

#include <time.h>

time_t time(time_t *timeptr);

 

이 함수는 1970년 1월 1일 0시 (UTC)부터 인자값(timeptr)까지 흐른 시간을 반환합니다. 그 단위가 초단위지요.  이 함수의 사용방법은 주로 2가지 입니다.

timeptr이라는 매개변수에 인자를 전달하여 현재까지 흐른 시간을 초단위로 구하거나, time함수에 NULL을 전달하여 반환값을 받거나 입니다.

 

 

 

그래서 현재시간까지 구한다면 time(NULL)을 호출해서 반환값을 받으면 되는 것이죠. 아래의 예처럼요.

time_t t; t = time(NULL); printf("%ld\n", t); 

그 결과는 아래처럼 큰 정수를 반환하게 되지요. 1970년 1월 1일 0시(UTC)부터 지금까지 초단위의 시간을 구하기 때문이지요.

1548588718

 

localtime

이 함수는 지역시간을 구해냅니다. 반환하는 형식은 구조체인데 tm이라는 구조체입니다. 다음 함수의 원형처럼 말이죠.

#include <time.h>

struct tm *localtime(const time_t *timeval);

 

우리는 위의 time함수에서 UTC기준으로 흐른 시간을 초단위로 구했지요. 초단위로 구하니 보기도 어렵고 지금이 몇월인지 몇년도인지 구분하기가 어렵습니다. 그래서 이것을 사람이 잘 알아보게끔 구조체로 변환할 수 있는 함수가 바로 localtime함수입니다.

 

 

 

 

우리는 반환값인 tm구조체를 다는 아니어도 필요한 몇가지 멤버는 알아야할 필요가 있습니다.

struct tm {

        int tm_sec;   //초

        int tm_min;   //분

        int tm_hour;   //시

        int tm_mday;  //일

        int tm_mon;    //월(0부터 시작)

        int tm_year;    //1900년부터 흐른 년

        int tm_wday;  //요일(0부터 일요일)

        int tm_yday;  //현재 년부터 흐른 일수

        int tm_isdst; 

};

필드명은 꽤 직관적입니다. 이 필드명만 보아도 무엇을 의미하는 것인지 잘 알것이라고 생각합니다.

자세한 것은 코드로 살펴보도록 합시다.

#include <stdio.h>
#include <time.h>

int main() { 
        time_t current;
        time(&current); 
        struct tm *t = localtime(&current);

        printf("%d년 %d월 %d일 ", 
                        1900 + t->tm_year, t->tm_mon + 1, t->tm_mday); 

        switch (t->tm_wday) {
                case 0:printf("일요일 "); 
                       break;
                case 1:printf("월요일 ");
                       break;
                case 2:printf("화요일 "); 
                       break; 
                case 3:printf("수요일 "); 
                       break;
                case 4:printf("목요일 "); 
                       break; 
                case 5:printf("금요일 ");
                       break;
                case 6:printf("토요일 "); 
                       break;
        } 

        printf("%d:%d:%d\n", t->tm_hour, t->tm_min, t->tm_sec);
        printf("1년 365일 중 %d일째\n", t->tm_yday + 1); 
}

 

그 결과는 다음과 같습니다.

2019년 1월 27일 일요일 20:55:9

1년 365일 중 27일째

각각 년, 월, 일 , 시, 분, 초, 요일을 각각 구할때, 또는 날짜계산, 시간계산을 할때 편리하겠군요.

 

ctime

 

#include <time.h>

char *ctime(const time_t *time);

구조체를 굳이 사용하고 싶지 않고 사용자가 시간을 읽을 수 있게끔 문자열로 변환하는 것이 ctime함수입니다. 마찬가지로 time함수에서 반환된 값을 ctime에 인자로 쏙 집어넣으면 현재 시간 정보를 다음과 같이 보기좋은 형식으로 반환해줍니다.

Www Mmm dd hh:mm:ss yyyy

 

Www 요일을 영어 세글자로 나타냅니다.

Mmm 월을 영어 세글자로 나타냅니다.

dd 날짜를 숫자 두글자로 나타냅니다.

hh 시를 숫자 두글자로 나타냅니다.

mm 분을 숫자 두글자로 나타냅니다.

ss 초를 숫자 두글자로 나타냅니다.

yyyy 년도를 숫자 네글자로 나타냅니다.

 

 

 

 

ctime이 어떤 함수인지 알았으면 어떻게 사용하는지 코드를 보세요. 몇 줄 안되는 코드입니다.

#include <stdio.h>
#include <time.h>

int main() { 
        time_t t = time(NULL); 
        printf("현재시간 :%s\n", ctime(&t));
}

 

코드는 상당히 간단합니다. 어떻게 나오는지 살펴보지요.

현재시간 :Sun Jan 27 21:07:50 2019

 

asctime

이 함수는 ctime과 같이 시간을 문자열로 출력해주지만 인자로 tm구조체 포인터를 받는 것과 ctime과 다른게 없습니다.

#include <time.h>

char *asctime(const struct tm *tm);

반환하는 문자열 포맷도 ctime과 똑같습니다. 사용방법은 그저 tm구조체 포인터를 전달하기만 하면 됩니다.

아래의 사용예를 보세요.

#include <stdio.h>
#include <time.h> 

int main() {
        time_t current = time(NULL);
        struct tm *t = localtime(&current); 
        printf("현재시간 :%s\n", asctime(t));
}
결과는 위의 ctime 결과와 같습니다.
여기까지 시간관련된 함수 4개를 살펴보았는데, 여기까지만 알면 충분할 것 같군요. 나중에 기회가 되면 더 살펴보도록 하지요.
반응형
블로그 이미지

REAKWON

와나진짜

,

우리는 난수를 사용하고 싶을 때가 있습니다. 하지만 이런 기능을 만드는 것은 좀처럼 쉬운 일은 아니지요. 귀찮기도 하구요.

C언어에서는 그러한 프로그래머를 위해서 난수생성함수를 제공하고 있습니다. 바로 rand라는 함수이지요. 외우기도 쉽네요. rand(om)으로 기억하면 되니까요.

 

rand

rand함수를 사용하기 위해서는 stdlib.h 헤더파일을 include해야합니다. rand함수는 0부터 RAND_MAX까지 범위까지 난수를 생성합니다. 함수 원형을 같이보시죠.

#include <stdlib.h>

int rand(void);

보시는 바와 같이 rand함수는 int형을 반환하게 됩니다. 아하, 그러면 rand함수를 쓰게 되면 랜덤인 정수형이 나오겠구나. 알 수 있죠?

이제 이 함수를 이용해서 1부터 100까지 정수 중 10개의 수를 랜덤하게 뽑아내는 프로그램을 짜보도록 하지요.

#include <stdio.h>
#include <stdlib.h> 

int main() { 
        int i; 
        for (i = 1; i <= 10; i++) 
                printf("%d ", (rand() % 100) + 1); 
        printf("\n");
}
이제 결과를 보도록 할까요??
 
42 68 35 1 70 25 79 59 63 65

 

 

오 랜덤하게 실행이 되는 군요. 100가지의 숫자 중 랜덤한 10개의 숫자를 뽑아냈습니다.

저는 신기해서 한번 더 실행해보겠습니다.

 

42 68 35 1 70 25 79 59 63 65

????

프로그램을 실행할때마다 바뀌지 않는데요? 우리는 이런 랜덤한 값을 원한게 아닙니다. 우리는 프로그램을 실행할때마다 랜덤하게 10개의 수를 출력하는 프로그램을 원하는 건데요. 지금 출력된 것은 단지 일정한 숫자 배열을 출력한 것과 같다고 느껴집니다.

왜 C언어는 우리에게 이런 사기를 치는 것일까요?

 

srand

사실 rand함수는 srand함수에 의존적입니다. srand의 s는 seed라는 뜻으로 이 seed값에 따라 rand의 값이 바뀌게 됩니다. srand는 rand함수와 같이 stdlib.h 헤더파일에 존재합니다.

만일 이 함수를 호출하지 않고 rand함수를 호출한다면 srand(1)을 호출하고 rand함수를 호출한 효과와 같습니다.

함수의 원형은 다음과 같은데요.

#include <stdlib.h>

void srand(unsigned int seed);

양의 정수만 seed로 사용할 수 있습니다. 그렇다면 우리가 srand의 seed값을 2로 주면 위의 결과와 다를까요?

위의 코드에서 for로프 위에 srand(2)를 추가해보세요.

46 17 99 96 85 51 91 32 6 17

 

아까와는 다른 결과를 볼 수 있군요. srand에서 seed를 바꿔서 실행시켜보세요. 나오는 값이 계속 달라짐을 알 수 있습니다. seed값만 바꿔주면 그 seed값에 따라 값을 랜덤하게 뽑아 올 수 있군요.

 

하지만 이것 마저도 아직 우리를 만족시킬 수가 없습니다. 이렇게 되면 프로그램을 실행시킬때마다 seed값을 바꾸고 다시 컴파일하는 과정을 거쳐야하기 때문이죠. 우리는 이런 허접한 코드는 쓰지 말도록 합시다.

 

우리는 이것보다 더 잘할 수 있습니다. 잘 할 수 있고 말고요. 한번 생각해봅시다. 프로그램 실행시 계속 바뀌는 값은 뭐가 있을까요?

주소값? (사실 제가 랜덤함수를 구현한다고 생각해볼때 고려해봤던 것 중 하나입니다.)

바로 시간입니다. 시간은 지금 이 순간에도 항상 바뀌고 있지요. 그래서 소개할 다음 함수가 time이라는 함수입니다.

time

time함수는 이름 그대로 시간에 대한 정보를 얻어오는 함수랍니다. 우선 time함수를 사용하기 위해서는 time.h라는 헤더파일을 include해야하지요.

함수의 원형을 한번 살펴볼까요?

#include <time.h>

time_t time(time_t *tloc);

 

이 함수는 1970년 1월 1일 0시 (UTC)부터 현재까지 흐른 시간을 반환합니다. 반환은 하지만 그 시간이 초단위입니다. 만일 우리가 현재까지 흐른 시간을 구하려면 만약 timeptr에 NULL을 전달하고 반환값을 받거나, 아니면 timeptr에 인자를 전달해서 현재까지 흐른 시간을 초단위로 받을 수 있습니다.

이제 아주 기본적인 사용법을 알게 됐으니 코드로 구현하도록 해봅시다. 

 

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() { 
        int i; 
        srand(time(NULL));

        for (i = 1; i <= 10; i++)  
                printf("%d ", (rand() % 100) + 1);
        printf("\n");
}

 

단지 srand의 인자를 time(NULL)로 바꾼거 밖에 없습니다. time(NULL)을 호출하면 1970/1/1 0시부터 현재(프로그램 실행 시)까지 흐른 시간을 return한다고 했지요? 그러니 이 프로그램을 실행할때마다 srand의 seed값이 바뀌게 되는 겁니다.

이제 확인을 해봅시다.

첫번째 실행

79 61 20 69 3 67 82 24 63 35

두번째 실행

44 53 56 15 86 98 95 14 15 46

어떻습니까? 이제 이 프로그램을 여러번 실행해도 값이 다르게 나온다는 것을 알 수 있습니다.

 

그렇다면 우리가 랜덤한 값을 얻고자 할때는 rand, srand, time함수를 전부 다 써야하나요?

네, 이 세가지 함수들은 묶어서 기억하셔야합니다. 사용법은 어렵지 안잖아요 그쵸??

 

이상으로 여기까지 C언어에서 난수를 생성하는 쉬운 방법을 알아보았습니다.

반응형
블로그 이미지

REAKWON

와나진짜

,