2015년 6월 3일 수요일

[C언어 예제] 가변인자 방식의 printf 구현하기 (2009)

(2009/06/11 16:15 작성)

출처: http://rabe.egloos.com/2166605


printf 함수나 scanf 함수의 경우 인자값을 가변적으로 전달할 수 있다.

이런 가변인자 방식은 system call 함수외에도 사용자 정의 함수에서도 사용할수 있다.

가변인자를 사용하는데 있어서 꼭 알아야 하는점은 최소 한개의 인자는 변수명을 지정해 주어야한다는 것이다.

그리고 특정위치의 인자값을 바로 불러 올수 있는 것이 아니라 처음 인자부터 차례대로 불러 올수 있다.

또한 인자를 불러올때 자료형을 반드시 알아야 정상적으로 불러올 수 있다.

가변 인자는 내부적으로 메모리 할당을 하므로 메모리 해제를 하지않으면 메모리 누수(Memory Leak)이 발생한다.

-헤더선언
#include <stdarg.h>

-함수선언
int j_printf(char *afmt,...);

-함수내에서의 초기화
va_start(sarg,afmt); 

-다음 인자값 읽어오기
char c = (char) va_arg(sarg,char); //char 형의 인자값일때
char *p = (char *) va_arg(sarg,char *); //char * 형의 인자값일때

-메모리해제
va_end(sarg);





(예제 소스)


#include <stdarg.h>

int main()
{
 j_printf("%d %s %d %s %d\n",300,"더하기",400,"",300+400);
 return 0;
}
int j_printf(char *afmt,...)
{
 int afmt_index=0;
 int arg_index=1;
 int afmt_len;
 int i;
 char t;
 char c;
 char *p;
 char tmp[11]; //int형 최대크기의 길이는 10자리수이므로
 int tmp_index;
 int in;
 va_list sarg;
 va_start(sarg,afmt); //뒤쪽 인수를 가리키기위한 초기화
 for(i=0;afmt[i];i++)
 {
  if(afmt[i]=='%')
  {
   i++;
   switch(afmt[i])
   {
   case 'c': //문자
    c=(char)va_arg(sarg,char);
    putchar(c);
    break;
   case 's': //문자열
    p = (char*)va_arg(sarg,char *);
    while(*p != '\0')
    {
     putchar(*p);
     p++;
    }
    break;
   case 'd': //정수형
    in = (int)va_arg(sarg,int);
    tmp_index=0;
    while(in) //ASCII to integer
    {
     tmp[tmp_index] = (in%10)+'0';
     in /= 10;    
     tmp_index++;
    }
    tmp_index --; //마지막 배열을 가리키도록 인덱스 값의 1을 빼줌
    while(tmp_index >=0)
    {
     putchar(tmp[tmp_index]);
     tmp_index--;
    }
    break;
   }
  }else{
   putchar(afmt[i]);
  }
 }
 va_end(sarg);
 return 0;
}

댓글 없음:

댓글 쓰기