마음의 안정을 찾기 위하여 - C언어의 printf 함수의 소스
2401867
384
500
관리자새글쓰기
태그위치로그방명록
별일없다의 생각
dawnsea's me2day/2010
색상(RGB)코드 추출기(Color...
Connection Generator/2010
최승호PD, '4대강 거짓말 검...
Green Monkey**/2010
Syng의 생각
syng's me2DAY/2010
천재 작곡가 윤일상이 기획,...
엘븐킹's Digital Factory/2010
C언어의 printf 함수의 소스
VC, MFC, C++ | 2007/12/12 10:00



/*
 Copyright 2001, 2002 Georges Menie (www.menie.org)
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.
    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
/*
 putchar is the only external dependency for this file,
 if you have a working putchar, just remove the following
 define. If the function should be called something else,
 replace outbyte(c) by your own function call.
*/
#define putchar(c) outbyte(c)
static void printchar(char **str, int c)
{
 extern int putchar(int c);
 if (str) {
  **str = c;
  ++(*str);
 }
 else (void)putchar(c);
}
#define PAD_RIGHT 1
#define PAD_ZERO 2
static int prints(char **out, const char *string, int width, int pad)
{
 register int pc = 0, padchar = ' ';
 if (width > 0) {
  register int len = 0;
  register const char *ptr;
  for (ptr = string; *ptr; ++ptr) ++len;
  if (len >= width) width = 0;
  else width -= len;
  if (pad & PAD_ZERO) padchar = '0';
 }
 if (!(pad & PAD_RIGHT)) {
  for ( ; width > 0; --width) {
   printchar (out, padchar);
   ++pc;
  }
 }
 for ( ; *string ; ++string) {
  printchar (out, *string);
  ++pc;
 }
 for ( ; width > 0; --width) {
  printchar (out, padchar);
  ++pc;
 }
 return pc;
}
/* the following should be enough for 32 bit int */
#define PRINT_BUF_LEN 12
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
{
 char print_buf[PRINT_BUF_LEN];
 register char *s;
 register int t, neg = 0, pc = 0;
 register unsigned int u = i;
 if (i == 0) {
  print_buf[0] = '0';
  print_buf[1] = '\0';
  return prints (out, print_buf, width, pad);
 }
 if (sg && b == 10 && i < 0) {
  neg = 1;
  u = -i;
 }
 s = print_buf + PRINT_BUF_LEN-1;
 *s = '\0';
 while (u) {
  t = u % b;
  if( t >= 10 )
   t += letbase - '0' - 10;
  *--s = t + '0';
  u /= b;
 }
 if (neg) {
  if( width && (pad & PAD_ZERO) ) {
   printchar (out, '-');
   ++pc;
   --width;
  }
  else {
   *--s = '-';
  }
 }
 return pc + prints (out, s, width, pad);
}
static int print(char **out, int *varg)
{
 register int width, pad;
 register int pc = 0;
 register char *format = (char *)(*varg++);
 char scr[2];
 for (; *format != 0; ++format) {
  if (*format == '%') {
   ++format;
   width = pad = 0;
   if (*format == '\0') break;
   if (*format == '%') goto out;
   if (*format == '-') {
    ++format;
    pad = PAD_RIGHT;
   }
   while (*format == '0') {
    ++format;
    pad |= PAD_ZERO;
   }
   for ( ; *format >= '0' && *format <= '9'; ++format) {
    width *= 10;
    width += *format - '0';
   }
   if( *format == 's' ) {
    register char *s = *((char **)varg++);
    pc += prints (out, s?s:"(null)", width, pad);
    continue;
   }
   if( *format == 'd' ) {
    pc += printi (out, *varg++, 10, 1, width, pad, 'a');
    continue;
   }
   if( *format == 'x' ) {
    pc += printi (out, *varg++, 16, 0, width, pad, 'a');
    continue;
   }
   if( *format == 'X' ) {
    pc += printi (out, *varg++, 16, 0, width, pad, 'A');
    continue;
   }
   if( *format == 'u' ) {
    pc += printi (out, *varg++, 10, 0, width, pad, 'a');
    continue;
   }
   if( *format == 'c' ) {
    /* char are converted to int then pushed on the stack */
    scr[0] = *varg++;
    scr[1] = '\0';
    pc += prints (out, scr, width, pad);
    continue;
   }
  }
  else {
  out:
   printchar (out, *format);
   ++pc;
  }
 }
 if (out) **out = '\0';
 return pc;
}
/* assuming sizeof(void *) == sizeof(int) */
int printf(const char *format, ...)
{
 register int *varg = (int *)(&format);
 return print(0, varg);
}
int sprintf(char *out, const char *format, ...)
{
 register int *varg = (int *)(&format);
 return print(&out, varg);
}
#ifdef TEST_PRINTF
int main(void)
{
 char *ptr = "Hello world!";
 char *np = 0;
 int i = 5;
 unsigned int bs = sizeof(int)*8;
 int mi;
 char buf[80];
 mi = (1 << (bs-1)) + 1;
 printf("%s\n", ptr);
 printf("printf test\n");
 printf("%s is null pointer\n", np);
 printf("%d = 5\n", i);
 printf("%d = - max int\n", mi);
 printf("char %c = 'a'\n", 'a');
 printf("hex %x = ff\n", 0xff);
 printf("hex %02x = 00\n", 0);
 printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
 printf("%d %s(s)%", 0, "message");
 printf("\n");
 printf("%d %s(s) with %%\n", 0, "message");
 sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
 sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
 sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
 sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
 sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
 sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
 sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
 sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
 return 0;
}
/*
 * if you compile this file with
 *   gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
 * you will get a normal warning:
 *   printf.c:214: warning: spurious trailing `%' in format
 * this line is testing an invalid % at the end of the format string.
 *
 * this should display (on 32bit int machine) :
 *
 * Hello world!
 * printf test
 * (null) is null pointer
 * 5 = 5
 * -2147483647 = - max int
 * char a = 'a'
 * hex ff = ff
 * hex 00 = 00
 * signed -3 = unsigned 4294967293 = hex fffffffd
 * 0 message(s)
 * 0 message(s) with %
 * justif: "left      "
 * justif: "     right"
 *  3: 0003 zero padded
 *  3: 3    left justif.
 *  3:    3 right justif.
 * -3: -003 zero padded
 * -3: -3   left justif.
 * -3:   -3 right justif.
 */
#endif

2007/12/12 10:00 2007/12/12 10:00
Article tag list Go to top
View Comment 1
Trackback URL :: 이 글에는 트랙백을 보낼 수 없습니다
From. 리오킴 2007/12/12 13:17
답글달기삭제
printf를 이렇게 복잡하게 -_-;;
PREV : [1] : NEXT
 
 
 
 
: [1] ... [668][669][670][671][672][673][674][675][676] ... [1323] :
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
전체 (1323)
출판 준비 (0)
My-Pro... (41)
사는 ... (933)
블로그... (22)
My Lib... (32)
게임 ... (23)
개발관... (3)
Smart ... (1)
Delphi (93)
C Builder (0)
Object... (0)
VC, MF... (10)
Window... (1)
Open API (3)
Visual... (0)
Java, JSP (2)
ASP.NET (0)
PHP (6)
Database (12)
리눅스 (29)
Windows (25)
Device... (1)
Embedded (1)
게임 ... (0)
Web Se... (2)
Web, S... (21)
잡다한... (7)
프로젝트 (0)
Personal (0)
대통령... (13)
Link (2)