본문으로 바로가기
homeimage
  1. Home
  2. 컴퓨터/프로그래밍
  3. C언어 날짜 시간 문자열 분리 팁

C언어 날짜 시간 문자열 분리 팁

· 댓글개 · 바다야크

C언어 날짜 시간 문자열 분리 팁

C언어는 문자열 처리하기가 참 까다롭습니다. 문자열을 합치는 간단한 일도 메모리를 따로 생성해서 복사해야 하는데, 다른 언어에 비하면 귀찮은 작업입니다. 문자열 합치기도 이러한데, 특정 문자열에서 일부를 분리해서 새로운 문자열을 만드는 것은 더욱 귀찮아집니다.

통신으로 날짜와 시간이 섞인 문자열을 받았습니다. 그 문자열에서 날짜와 시간을 분리해서 화면에 출력하려고 합니다. 예를 들어서 "badayak.com20220920150525jwmx.tistory.com" 이런 데이터를 받으면 "데이터 날짜: 2022년 09월 20일 15시 05분 25초"로 화면에 출력하고 싶습니다. 그래서 아래와 같이 코드를 작성했습니다.

C언어 memcpy() 함수 사용

#include <stdio.h>
#include <string.h>

int main( void){

    char rcv_data[] = "badayak.com20220920150525jwmx.tistory.com";
    char str_date[1024];

    memcpy(  str_date, &rcv_data[11], 4);
    memcpy( &str_date[ 4], "년 ", 4);
    memcpy( &str_date[ 8], &rcv_data[15], 2);
    memcpy( &str_date[10], "월 ", 4);
    memcpy( &str_date[14], &rcv_data[17], 2);
    memcpy( &str_date[16], "일 ", 4);
    memcpy( &str_date[20], &rcv_data[19], 2);
    memcpy( &str_date[22], "시 ", 4);
    memcpy( &str_date[26], &rcv_data[21], 2);
    memcpy( &str_date[28], "분 ", 4);
    memcpy( &str_date[32], &rcv_data[23], 2);
    memcpy( &str_date[34], "초", 3);
    str_date[37] = '\0';

    printf( "데이터 날짜: %s\n", str_date);

    return 0;
}

통신 데이터가 "2022년 09월 20일 15시 05분 25초"으로 오면 참 좋으련만, 뭉터기로 오다 보니 memcpy() 함수를 사용해서 일일이 잘라서 붙여 넣듯 복사했습니다. 배열의 요소 번호를 입력하려고 숫자 셈을 하면서 코딩했는데요, 수고한 덕분에 잘 작동합니다. 이 보다 좀 더 간단하게 코딩할 수 없을까요?

C언어 strcpy() 함수 사용

#include <stdio.h>
#include <string.h>

int main( void){

    char rcv_data[] = "badayak.com20220920150525jwmx.tistory.com";
    char str_date[1024];

    memcpy(  str_date, &rcv_data[11], 4);
    strcpy( &str_date[ 4], "년 ");
    memcpy( &str_date[ 8], &rcv_data[15], 2);
    strcpy( &str_date[10], "월 ");
    memcpy( &str_date[14], &rcv_data[17], 2);
    strcpy( &str_date[16], "일 ");
    memcpy( &str_date[20], &rcv_data[19], 2);
    strcpy( &str_date[22], "시 ");
    memcpy( &str_date[26], &rcv_data[21], 2);
    strcpy( &str_date[28], "분 ");
    memcpy( &str_date[32], &rcv_data[23], 2);
    strcpy( &str_date[34], "초");
    str_date[37] = '\0';

    printf( "데이터 날짜: %s\n", str_date);

    return 0;
}

년월일시분초 글자를 삽입하는 것으로는 memcpy()보다는 strcpy()가 편합니다만, sprintf()를 이용하면 매우 간단하게 처리할 수 있습니다. 

C언어 sprintf() 함수 사용

#include <stdio.h>
#include <string.h>

int main( void){

    char rcv_data[] = "badayak.com20220920150525jwmx.tistory.com";
    char str_date[1024];

    sprintf( str_date, "    년   월   일   시   분   초");
    memcpy(  str_date, &rcv_data[11], 4);
    memcpy( &str_date[ 8], &rcv_data[15], 2);
    memcpy( &str_date[14], &rcv_data[17], 2);
    memcpy( &str_date[20], &rcv_data[19], 2);
    memcpy( &str_date[26], &rcv_data[21], 2);
    memcpy( &str_date[32], &rcv_data[23], 2);

    printf( "데이터 날짜: %s\n", str_date);

    return 0;
}

어떻습니까? 미리 년월일시분초 문자를 넣어서 문장 틀을 만들어 놓고 그 사이사이에 날짜와 시간을 넣는 것이죠. 코딩이 간단해졌지만, sprintf() 함수의 서식을 제대로 활용하지 못했습니다. printf() 함수와 sprintf() 함수의 서식 중 문자열을 입력받는 %s에 점을 넣어 길이를 표시하면 즉, %[숫자]s로 표시하면 숫자만큼 길이를 잘라내어 문장을 완성하게 됩니다.

C언어 printf() 서식 활용

#include <stdio.h>

int main( void){

    char rcv_data[] = "badayak.com20220920150525jwmx.tistory.com";
    char str_date[1024];
    
    sprintf( str_date, "%.4s년 %.2s월 %.2s일 %.2s시 %.2s분 %.2s초", 
        &rcv_data[11], &rcv_data[15], &rcv_data[17], 
        &rcv_data[19], &rcv_data[21], &rcv_data[23]);
    
    printf( "데이터 날짜: %s\n", str_date);

    return 0;
}

&rcv_data[11]은 rcv_data 배열에서 날짜가 시작하는 주소입니다. 즉, "20220920150525jwmx.tistory.com"이 됩니다. 이 문자열에 대해서 printf()나 sprintf()의 서식에서 %.4s로 작성하면 4개 문자까지 대입해 줍니다. 만일 점 없이 %4s라고 하면  &rcv_data[11]이 가리키는 문자열 "20220920150525jwmx.tistory.com"은 길이가 4 이상이므로 "20220920150525jwmx.tistory.com"가 대입됩니다. "20"처럼 길이가 4보다 짧은 문자열이어야 지정한 숫자의 길이에 맞추어 "  20"이 대입됩니다.

sprintf()보다 snprintf()

이와 같이 sprintf()와 서식을  활용하면 문자열을 쉽게 처리하고 생성할 수 있습니다. 단, sprintf()는 매우 편리한 함수이지만, 생성되는 문자열을 모두 받을 수 있을 정도로 변수의 메모리의 크기가 여유 있을 정도로 커야 합니다. 만일 생성되는 문자열 길이를 확신할 수 없고, 그래서 생성된 변수의 크기가 부족해서 위험할 수 있다고 예상된다면 변수의 메모리 크기를 충분히 키우거나 생성되는 문자열 길이를 제한할 수 있는 snprintf()를 사용하는 것이 안전합니다.

SNS 공유하기
💬 댓글 개
최근글
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.