소감

일단 되게만 만들자라는 생각을 먼저하고 짜서 그런가 중복되는 것도 매우 많아져서 전체적으로 코드가 길어졌다.

코드

~cpp
#include <iostream>
#include <cstdlib>
#include <stdarg.h>
#include <cctype>
using namespace std;

void print(const char *, ...);

int main()
{
	int a = 10; 
	char *b = "example"; 
	double c = 10.5;
	print("number: %d, string: %s, real number: %f\n", a, b, c); 
	print("%d. 1234 string %s %f\n", 1234, "test", 1234.124124);


	int aa[3] = {1, 2, 3}; 
	char *bb[2] = {"abc", "def"}; 
	double cc[5] = {3.1, 3.2, 314.12451, -123654.12351, 0.12412431};
	print("array: @d\n", aa, 3); 
	print("array: @s\n", bb, 2);
	print("array: @f\n", cc, 5);


	int aaa = 123; 
	int bbb = 12345; 
	int ccc = 12345678;
	char *aaaa = "example";
	double cccc = 124.113;
	print("number: %5d\n", aaa); 
	print("number: %5d\n", bbb); 
	print("number: %5d\n", ccc);
	print("string: %9s\n", aaaa);
	print("number: %9f\n", cccc);
 
	return 0;
}

void print(const char *arg, ...)
{
	char print_string[1024];
	va_list vargs;					// 가변인자 리스트
	int arg_index = 0;
	
	va_start(vargs, arg);

	while (arg[arg_index] != '\0')
	{
		if (arg[arg_index] == '%')
		{
			arg_index++;

            int align = 0; 
            if(isdigit((int)arg[arg_index])) 
            { 
                align = arg[arg_index] - '0'; 
                arg_index++;
            } 

			if (arg[arg_index] == 'd')			// 정수형 출력
			{
				int print_integer = va_arg(vargs, int);
				itoa(print_integer, print_string, 10);
				
				int space = align - strlen(print_string); 
				for(int i = 0 ; i < space ; i++) 
					putchar(' ');
				fputs(print_string, stdout);
			}
			else if (arg[arg_index] == 's')		// string(char *)형 출력
			{
				char *s = va_arg(vargs, char *);
				strcpy(print_string, s);
				
				int space = align - strlen(print_string); 
				for(int i = 0 ; i < space ; i++) 
					putchar(' ');
				fputs(print_string, stdout);
			}
			else if (arg[arg_index] == 'f')		// float형 출력
			{
				int decimal, sign, zero_position, index = 0;
				double print_double = va_arg(vargs, double);
				char *s = _fcvt(print_double, 7, &decimal, &sign);
				
				// 소수점아래 7자리까지 출력이므로 소수점 뒤에 0을 제거해야 한다.
				zero_position = strlen(s) - 1;
				while (s[zero_position] == '0')
					zero_position--;

				// 소수점을 포함한 숫자의 개수
				int space = align - zero_position - 2; 
				for(int i = 0 ; i < space ; i++) 
					putchar(' ');

				// 부호 출력
				if (sign == 1)
					putchar('-');

				// 0.xxx 일경우 0 표시)
				if (decimal == 0)	
					putchar('0');
	
				for (int i = 0; i <= zero_position; i++)
				{
					if (i == decimal)	// 소수점 위치 찍기
						putchar('.');
					putchar(s[i]);
				}
			}
			arg_index++;
		}
		else if (arg[arg_index] == '@')
		{
			arg_index++;
			if (arg[arg_index] == 'd')			// 정수형 배열 출력
			{
				int *int_array = va_arg(vargs, int*);
				int array_size = va_arg(vargs, int);
				
				putchar('{');
				for (int i = 0; i < array_size; i++)
				{
					putchar(' ');
					itoa(int_array[i], print_string, 10);
					fputs(print_string, stdout);
					
					if (i < array_size - 1)
						putchar(',');
				}
				putchar(' ');
				putchar('}');
			}
			else if (arg[arg_index] == 's')		// string(char *)형 배열 출력
			{
				char **string_array = va_arg(vargs, char**);
				int array_size = va_arg(vargs, int);
				
				putchar('{');
				for (int i = 0; i < array_size; i++)
				{
					putchar(' ');
					strcpy(print_string, string_array[i]);
					fputs(print_string, stdout);
					
					if (i < array_size - 1)
						putchar(',');
				}
				putchar(' ');
				putchar('}');
			}
			else if (arg[arg_index] == 'f')		// float형 배열 출력
			{
				double *double_array = va_arg(vargs, double*);
				int array_size = va_arg(vargs, int);
				
				putchar('{');
				for (int i = 0; i < array_size; i++)
				{
					putchar(' ');
					int decimal, sign, zero_position, index = 0;
					char *s = _fcvt(double_array[i], 7, &decimal, &sign);

					// 부호 출력
					if (sign == 1)
						putchar('-');

					// 0.xxx 일경우 0 표시)
					if (decimal == 0)	
						putchar('0');

					// 소수점아래 7자리까지 출력이므로 소수점 뒤에 0을 제거해야 한다.
					zero_position = strlen(s) - 1;
					while (s[zero_position] == '0')
						zero_position--;

					for (int j = 0; j <= zero_position; j++)
					{
						if (j == decimal)	// 소수점 위치 찍기
							putchar('.');
						putchar(s[j]);
					}
					
					if (i < array_size - 1)
						putchar(',');
				}
				putchar(' ');
				putchar('}');
			}
			arg_index++;
		}
		else
		{
			putchar(arg[arg_index]);
			arg_index++;
		}
	}
}
Retrieved from http://wiki.zeropage.org/wiki.php/OurMajorLangIsCAndCPlusPlus/print/이도현
last modified 2021-02-07 05:23:57