Author | Created | Updated |
mcha(Min-jae Cha) | 2022. 01. 13 | 2022. 01. 13 |
Subtitle
Because putnbr and putstr arenβt enough
Version
9
Specification
Function name | ft_printf |
Prototype | int ft_printf(const char *, ...); |
Turn in files | .c, /.c, *.h, /.h, Makefile |
Makefile | all, clean, fclean, re, bonus |
External functs. | malloc, free, write, va_start, va_arg, va_copy, va_end |
Description | Write a library that contains ft_printf, a function that will mimic the real printf |
1. Summary
β libcμ printf ν¨μλ₯Ό μ¬κ΅¬ν
printf ν¨μλ <stdio.h> λΌμ΄λΈλ¬λ¦¬μ ν¬ν¨λμ΄ μλ€.
printfμ fλ formattedμ μ½μμ΄λ€. μ΄κ²μ formattedλ μΆλ ₯μ νμ νλ λ° μ°μΈλ€.
printfμ λ€μ΄κ°λ format placeholderλ€μ λ§€μ° λ§λ€.
%[parameter][flags][width][.precision][length]type
μ΄ μ€ μ°λ¦¬κ° ꡬνν΄μΌ ν κ²(Version : 9) : flags, width, type, precision
κ°λ³ μΈμ (variadic arguments)
κ°μμ νμ
μ΄ μ ν΄μ Έ μμ§ μκ³ κ°λ³ ν μ μλ μΈμ
ν¨μμ μ΄λ¦μ΄λ μν, κ³ μ μΈμμ κ°μ λ±μ νμμ λ°λΌ μμ λ‘κ² μμ±ν μ μλ€.
λ§μ§λ§ μΈμ μ리μ "..."λ§ μμΌλ©΄ κ°λ³ μΈμ ν¨μκ° λ§λ€μ΄μ§λ€.
int a(int x, int y);
int b(int x, int y, ...);
printf("str", ..); => str 1 2
C
볡μ¬
ꡬ쑰
β va_list ap
Prototype : char *va_list
ν¨μλ‘ μ λ¬ λλ μΈμλ€μ μ€ν(Stack)μ μ μ₯λμ΄ ν¨μλ μ€νμμ μΈμλ₯Ό κΊΌλ΄μ΄ μ¬μ©νλ€.
μ€νμ μΈμλ₯Ό μ½μ λ ν¬μΈν° μ°μ°μ ν΄μΌ νλλ° νμ¬ μ½κ³ μλ λ²μ§λ₯Ό κΈ°μ΅νκΈ° μν΄ va_list νμ ν¬μΈν° λ³μ νλκ° νμνλ€.
β va_start(ap, λ§μ§λ§ κ³ μ μΈμ)
ap ν¬μΈν° λ³μκ° μ²« λ²μ§Έ κ°λ³ μΈμλ₯Ό κ°λ¦¬ν€λλ‘ μ΄κΈ°ν
첫 λ²μ§Έ κ°λ³ μΈμμ λ²μ§λ₯Ό μ‘°μ¬νκΈ° μν΄ λ§μ§λ§ κ³ μ μΈμλ₯Ό μ λ¬νλ€.
va_start λ΄λΆμμλ apκ° λ§μ§λ§ κ³ μ μΈμ λ€μ λ²μ§λ₯Ό κ°λ¦¬ν€λλ‘ ν΄μ£Όμ΄, μ΄νλΆν° apλ²μ§λ₯Ό μ½μΌλ©΄ μμλλ‘ κ°λ³ μΈμλ₯Ό μ½μ μ μλ€.
β va_arg(ap, μΈμ νμ )
κ°λ³ λ³μλ₯Ό μ€μ λ‘ μ½λ λͺ
λ Ή
va_startκ° apλ₯Ό 첫 λ²μ§Έ κ°λ³ μΈμ λ²μ§λ‘ λ§μΆμ΄ μ£ΌκΈ° λλ¬Έμ ap μμΉμ μλ κ°μ μ½κΈ°λ§ νλ©΄ λλ€.
λ¨, ap λ²μ§μ μλ κ°μ΄ μ΄λ€ νμ
μΈμ§λ₯Ό μ§μ ν΄μΌ μ΄ λ§€ν¬λ‘κ° κ°μ μ λλ‘ μ½μ μ μλ€.
λ°λΌμ va_argμ λ λ²μ§Έ νλΌλ―Έν°μ μ½κ³ μ νλ κ°μ νμ
(type)μ μ§μ νλ€.
va_arg(ap, int) != va_arg(ap, char)
C
볡μ¬
μλ₯Ό λ€μ΄ ap μμΉμ μλ μ μ κ°μ μ½κ³ μ νλ€λ©΄ va_arg(ap, int)λ₯Ό νΈμΆνκ³ , μ€μ κ°μ μ½κ³ μ νλ©΄ va_arg(ap, double)μ νΈμΆνλ©΄ λλ€.
va_argμ λ λ²μ§Έ μΈμλ λ³μ λͺ
μ΄ μλ typeμΈλ° μ΄λ»κ² ν¨μμ μΈμκ° λ μ μλ?
β va_argλ μΌλ° ν¨μκ° μλ 맀ν¬λ‘ ν¨μμ΄κΈ° λλ¬Έμ΄λ€.
va_argμ λ λ²μ§Έ μΈμλ λ΄λΆμ μΌλ‘ sizeof μ°μ°μμ μΊμ€νΈ μ°μ°μλ‘ μ λ¬λκΈ° λλ¬Έμ νμ
λͺ
μ΄ νλΌλ―Έν°λ‘ λ€μ΄μ¬ μ μλ€.
β va_end(ap)
Β κ°λ³ μΈμλ₯Ό λ€ μ½μ ν λ· μ 리λ₯Ό νλλ° μ¬μ©λλ€. μ¬μ€ μ€μ λ‘ μμ΄λ μ ν μ§μ₯μ΄ μλ€.
va_endκ° νμν μ΄μ λ νΈνμ± λλ¬ΈμΈλ°, νλ«νΌμ λ°λΌμλ κ°λ³ μΈμλ₯Ό μ½μ νμ λ· μ²λ¦¬λ₯Ό ν΄μΌ νλ κ²½μ°λ μκΈ° λλ¬Έμ΄λ€.
λ°λΌμ μ€μν μν μ ν μλ μκΈ° λλ¬Έμ κ΄λ‘μ μΌλ‘ λ£μ΄ μ£Όλ κ²μ΄ μ’λ€.
κ°λ³ μΈμλ€μ ν©ν΄μ λ°ννλ μμ
#include <stdio.h>
#include <stdarg.h>
int test(int c, ...)
{
int arg;
int sum;
int i;
va_list ap;
sum = 0;
i = 0;
va_start(ap, c);
while (i < 5)
{
arg = va_arg(ap, int);
sum += arg;
i++;
}
va_end(ap);
return (sum);
}
int main(void)
{
printf("result1 => %d\n", test(1, 1,1,1,1,1));
printf("result2 => %d\n", test(2, 2,2,2,2,2));
printf("result3 => %d\n", test(3, 3,3,3,3,3));
printf("result4 => %d\n", test(4, 4,4,4,4,4));
printf("result5 => %d\n", test(5, 5,5,5,5,5));
return (0);
}
C
볡μ¬
κ°λ³ μΈμ ν¨μμ 쑰건
β κ°λ³ μΈμ ν¨μλ λ°λμ νλ μ΄μμ κ³ μ μΈμλ₯Ό κ°μ ΈμΌ νλ€.
ν¬μΈν° ap(va_list ap)λ₯Ό μ΄κΈ°ν νκΈ° μν΄ va_startλ₯Ό μ¬μ©νμ¬ λ§μ§λ§ κ³ μ μΈμλ₯Ό 보λ΄μ£Όλλ°,
κ³ μ μΈμκ° μ‘΄μ¬νμ§ μλ€λ©΄ κ°λ³ μΈμμ μμ λ²μ§κ° μ΄λμΈμ§ λͺ¨λ₯΄κΈ° λλ¬Έμ΄λ€.
κ³ μ μΈμκ° μ‘΄μ¬νμ§ μλλ€λ©΄ κ°μ₯ μ²μμ λ€μ΄μ¨ μΈμκ° κ°λ³ μΈμμ μμμ΄μ§ μμκ°?
1. int test(int a, ...);
2. int test(...);
β ν¨μ λ΄λΆμμ μμ μκ² μ λ¬ λ κ°λ³ μΈμμ κ°μλ₯Ό νμ
ν μ μλλ‘ ν΄μΌνλ€.
νλΌλ―Έν°λ‘ λ°μ μ€λ μΈμμ κ°μμλ μ νμ΄ μκ³ μ»΄νμΌλ¬λ ν¨μκ° νΈμΆ λ λ μΈμμ κ°μλ₯Ό κ²μ¬νμ§ μλλ€.
λ°λΌμ κ°λ³ μΈμκ° λͺ κ°λ μ λ¬ λμλμ§ μλ €μ£Όμ§ μμΌλ©΄ ν¨μ λ΄λΆμμ μΈμμ κ°μλ₯Ό μ μ μλ λ°©λ²μ΄ μλ€. κ·Έλ¬λ―λ‘ νΈμΆ μΈ‘μμ ν¨μμ κ°λ³ μΈμμ κ°μμ λν μ 보λ₯Ό μ 곡ν΄μΌνλ€.
β ν¨μ λ΄λΆμμ κ°λ³ μΈμ κ°κ°μ νμ
μ μ μ μμ΄μΌ νλ€.
va_arg 맀ν¬λ‘κ° apλ²μ§μμ κ°λ³ μΈμλ₯Ό μ½μ λ μΌλ§λ§νΌ μ½μ΄μ μ΄λ€ νμ
μΌλ‘ ν΄μν΄μΌ ν μ§λ₯Ό μμμΌ νκΈ° λλ¬Έ
printfλ₯Ό μλ₯Ό λ€μ΄ %dκ° μ μΌ μ²μ λμμΌλ©΄ 첫 λ²μ§Έλ μ μ, %fκ° λμ€λ©΄ μ€μλΌλ κ²μ μκ² λλ€.
κ°λ³ μΈμμ νμ
μ μ λ¬νλ λ°©μλ μ¬λ¬ κ°μ§λ₯Ό μκ°ν μ μλλ°, printfμ κ°μ΄ νλμ κ³ μ μΈμλ₯Ό ν΅ν΄ λͺ¨λ κ°λ³ μΈμμ νμ
μ νλ¨ν μ μλ ννΈλ₯Ό μ 곡νλ λ°©μμ΄ κ°μ₯ μ’λ€.
#include <stdio.h>
#include <stdarg.h>
int test(const char *s, ...)
{
int sum;
int arg;
va_list ap;
sum = 0;
va_start(ap, s);
for(;;)
{
arg = va_arg(ap, int);
if (arg == 0)
break ;
sum += arg;
}
va_end(ap);
return (sum);
}
int main(void)
{
printf("result1 (1 + 2) => %d\n", test("1+2 => %d\n", 1, 2, 0));
printf("result2 (3 + 4 + 5 + 6) => %d\n", test("3+4+5+6 => %d", 3, 4, 5, 6, 0));
printf("result3 (10 + 11 + 12 + 13) => %d\n", test("10 ~ 13 => %d", 10, 11, 12, 13, 0));
return (0);
}
C
볡μ¬
2. Placeholders
1) flags (optional)
Character | Description | Default |
-
(minus) | μ§μ λ νλ width λ΄μμ μΌμͺ½ μ λ ¬ | μ°μΈ‘ μ λ ¬ |
+
(plus) | μμλ©΄ '+' λΆνΈλ₯Ό, μμλ©΄ '-' λΆνΈλ₯Ό νμνλ€. | μμλ§ λΆνΈ νμ |
' '
(space) | μμμΈ κ²½μ°μλ μμ 곡백 μ½μ
, μμμΈ κ²½μ°μλ '-' λΆνΈ νμ
λ§μ½ '+' flagκ° μ‘΄μ¬νλ€λ©΄ 곡백 flagλ 무μλλ€. | μμ λΆνΈ μμ |
0
(zero) | 'width' μ΅μ
μ΄ μ§μ λ κ²½μ° μ«μ νμ μμ 0μ΄ λΆλλ€.
λ§μ½ '-' flagκ° μ‘΄μ¬νλ€λ©΄ '0' flag λ 무μλλ€. | |
#
(hash) | typeμ o,x,Xμ μ¬μ© λ κ²½μ° 0μ΄ μλ κ°μ λν΄ 0, 0x ,0Xκ° κ°μ΄ νμλλ€.
typeμ e, E, f, F, g, G μ ν¨κ» μ¬μ©ν κ²½μ°, μ«μ λ€μ μ€λ κ²μ΄ μμ΄λ μμμ μ ν¬ν¨νλλ‘ κ°μ . |
2) width (optional)
Character | Description |
(number) | μΆλ ₯ λ μ΅μ λ¬Έμ μ.
μΆλ ₯ν κ°μ΄ μ΄ κ°λ³΄λ€ 짧μΌλ©΄ κ²°κ³Όλ 곡백μΌλ‘ μ±μμ§λ€. λ°λλ‘ κ²°κ³Όκ° λ ν¬λλΌλ κ°μ΄ μλ¦¬μ§ μλλ€. |
* | λλΉ κ°μ μΈμλ‘ λ°μμ μ¬μ©νλ€.
μΈμλ‘ λ°μ κ°λ³΄λ€ λ κΈ΄ κ°μ΄ λ€μ΄μ€λ©΄ μλ κΈΈμ΄λ§νΌ μΆλ ₯νλ€. |
printf("%5d", 42);
// '*'μ μ¬μ©νμ¬ λλΉ κ°μ μΈμλ‘ λ°μ λͺ¨μ΅
printf("%*d", 5, 42);
C
볡μ¬
β width β₯ λ¬Έμμ΄μ κΈΈμ΄
width κ° λ§νΌ 곡κ°μ λ§λ λ€ μ°μΈ‘ μ λ ¬ νμ¬ λ¬Έμμ΄μ νμνλ€
#include <stdio.h>
int main(void)
{
printf("%*d", 6, 1234);
return (0);
}
C
볡μ¬
β width < λ¬Έμμ΄μ κΈΈμ΄
widthμ κ°μ 무μνκ³ λ¬Έμμ΄μ κΈΈμ΄λ§νΌ μΆλ ₯νλ€
#include <stdio.h>
int main(void)
{
printf("%*d", 6, 1234567);
return (0);
}
C
볡μ¬
3) .precision (optional)
μΆλ ₯νλ κ°μ μ νλ νκΈ°λ₯Ό μν νλλ‘, width νλ λ€μμΌλ‘ λνλλ νλμ΄κΈ° λλ¬Έμ νλ κ° κ΅¬λΆμ μν΄ .μ νμμ μΌλ‘ μ¬μ©λλ€. λ¨λ
μΌλ‘ .μ΄ μ΄μ© λκΈ°λ νλ©° .κ³Ό μ«μ(number)λ₯Ό μ‘°ν©νμ¬ μ¬μ©νκΈ°λ νλ€.
κ°κ°μ κ²½μ°μλ type νλμ μ΅μ
(μ’
λ₯)μ λ°λΌ μΆλ ₯ κ°μ΄ λ°λλ€.
Β μ΄ μ΅μ
μ width, length, typeμ λ°λΌ μν₯μ λ°κΈ° λλ¬Έμ μ μν΄μ μ²λ¦¬ν΄μΌ νλ€.
β Usability
Declaration | Character | Description |
. | [type] | λ¨λ
μΌλ‘ .λ§ μ¬μ©λ κ²½μ° |
c, p | μ νλλ₯Ό 무μνκ³ type μ΅μ
μ λ°λ₯Έ κ°μ μΆλ ₯ | |
d, i, o, u, x, X | flags νλμ 0μ΄ μ£Όμ΄μ§λ©΄, μ΅μ
0μ 무μνκ³ μ²λ¦¬ | |
f, e, E, g, G, a, A | μμμ μλ μΆλ ₯νμ§ μμ. λ§μ§λ§ μ«μλ λ°μ¬λ¦Όνμ¬ μ²λ¦¬ | |
s | λ¬Έμμ΄μ μΆλ ₯νμ§ μμ | |
*s | μΆλ ₯ν μ΅λ κΈΈμ΄λ₯Ό μΈμλ‘ λ겨 λ°μ, ν΄λΉ κΈΈμ΄ λ§νΌλ§ λ¬Έμμ΄ μΆλ ₯ | |
.n | [type] | μ μ«μλ₯Ό μλ―Ένλ©°, μμλ§ μ¬μ©ν μ μλ€.
μμλ₯Ό μ¬μ©νλ©΄ widthμ μ΅μ
κ°μ 무μνκ³ , .precisionμ κ°μΌλ‘ λ€μ΄μ¨ μμ λ§νΌμ widthμ μ΅μ
κ°μΌλ‘ μΈμνλ€. widthμμμ μμ μ²λ¦¬ λ°©μμ λ°λ₯΄λ―λ‘ μ’μΈ‘ μ λ ¬μ μννλ€. |
c | μ νλλ₯Ό 무μνκ³ type μ΅μ
μ λ°λ₯Έ κ°μ μΆλ ₯ | |
d, i, o, u, x, X | μΆλ ₯ν μ΅λ μλ¦Ώμλ₯Ό μ§μ .
μλ¦Ώμμμ μΆλ ₯ν κ°μ κΈΈμ΄λ₯Ό λΊ λ¨μ 곡κ°μ κΈ°λ³Έμ μΌλ‘ 0μΌλ‘ μΆλ ₯.
μΆλ ₯ νκ³ μ νλ μ μ κ°μ΄ 0μ΄κ³ , λν 0μ΄λΌλ©΄ μΆλ ₯ κ°μ΄ μμ. | |
f, e, E, g, G, a, A | μΆλ ₯ν μμμ μλ¦Ώμ μ§μ .
μΆλ ₯ν μ리 μ§νμ μ«μλ₯Ό λ°μ¬λ¦Όνμ¬ μλ¦Ώμ λ΄μ μΆλ ₯ν μ μλλ‘ νλ€.
μ€μ κ°μΌλ‘ 0.0μ΄ λ€μ΄μλλ° nμ΄ 0μ΄λΌλ©΄ 0μ μΆλ ₯νλ€. | |
s | λ¬Έμμ΄μμ μΆλ ₯ν μ΅λ κΈΈμ΄λ₯Ό μ§μ .
μ€μ ν κΈΈμ΄κ° λ¬Έμμ΄λ³΄λ€ ν¬λ€λ©΄ μλ κΈΈμ΄μ λ¬Έμμ΄μ μΆλ ₯
if (n > strlen(s)) β print(s) | |
p | 0xλ₯Ό μ μΈνκ³ μ΄ κΈΈμ΄λ₯Ό μ£Όμ΄μ§ μ λ§μΆμ΄ μΆλ ₯νλ€. |
[1] λ¨λ μΌλ‘ .λ§ μ¬μ©λ κ²½μ°
c, p
d, i, o, u, x, X
s
[2] .μ μ«μλ₯Ό λͺ μνμ¬ typeμ λ°λ₯Έ μμ
c, p
d, i, o, u, x, X
s
κ° μμ μ§μ μ λ³ νλκ·Έμ μμ©
type \ flag | '-' | '+' | '(space)' | '#' | '0' | precision(μ λ°λ) |
d | width νλ λ΄μμ μ’μΈ‘ μ λ ¬
[ '0' ]
β ignored Error | μμ(0 ν¬ν¨)μΈ κ²½μ° μμ '+' λΆνΈ μ½μ
[ ' ' ]
β ignored Error | μμ(0 ν¬ν¨)μΈ κ²½μ° μμ ' 'λΆμΈλ€.
[ '+' ]
β ignored Error | Undefined | νλμμ λΉ μΉΈμ '0' λ¬Έμλ‘ μ±μ΄λ€.
[ '-', μ λ°λ ]
β ignored Error | μΆλ ₯λ μλ¦Ώμλ₯Ό μ§μ |
i | μμ κ°μ | μμ κ°μ | μμ κ°μ | Undefined | μμ κ°μ | μμ κ°μ |
u | μμ κ°μ | Undefined | Undefined | Undefined | μμ κ°μ | μμ κ°μ |
x | μμ κ°μ | Undefined | Undefined | μ«μ μμ '0x' λΆμ¬μ€λ€.
[ μ λ°λ ]
β μλ¦Ώμ μΉ΄μ΄νΈ μν¨ | μμ κ°μ
#κ³Ό κ°μ΄ μ°μ΄λ κ²½μ°λ 0xμ μ«μ μ¬μ΄μ '0'μ΄ λ€μ΄κ°λ€. | μμ κ°μ |
X | μμ κ°μ | Undefined | Undefined | μ«μ μμ '0X' λΆμ¬ μ€λ€.
[ μ λ°λ ]
β μλ¦Ώμ μΉ΄μ΄νΈ μν¨ | μμ κ°μ
μμ κ°μ
#κ³Ό κ°μ΄ μ°μ΄λ κ²½μ°λ 0Xμ μ«μ μ¬μ΄μ '0'μ΄ λ€μ΄κ°λ€. | μμ κ°μ |
s | μμ κ°μ | Undefined | Undefined | Undefined | Undefined | μ΅λ μΆλ ₯ λ¬Έμ κ°μ |
c | μμ κ°μ | Undefined | Undefined | Undefined | Undefined | Undefined |
p | μμ κ°μ | Undefined | Undefined | Undefined | Undefined | Undefined |
%(percentage) | μμ κ°μ |
Consider
1) ' % '
%μ % μ¬μ΄μ μ΄λ νλκ·Έκ° μμ΄λ λ€ λ¬΄μνλ€.
μμ (μ€μ)
2) .precision vs width
μμκ° λ€μ΄κ°μ κ²½μ°μ μΆλ ₯κ°
μμ
Ignored Combination
1) ' -0 ' or ' 0- '
#include <stdio.h>
int main(void)
{
printf("================= Test 'd' =================\n");
printf("%-0d\n", 10);
printf("%+d\n", 10);
return (0);
}
C
볡μ¬
2) ' (space)+ ' or ' +(space) '
#include <stdio.h>
int main(void)
{
printf("================= Test 'd' =================\n");
printf("% +d\n", 10);
printf("% d\n", 10);
return (0);
}
C
볡μ¬
Undefined Combination
1) ' +u ', ' +x ', ' +X ', ' +c ' , ' +p ', ' +s '
#include <stdio.h>
int main(void)
{
printf("================= Test 'u' =================\n");
printf("%+u\n", 10);
printf("%u\n", 10);
return (0);
}
C
볡μ¬
2) ' (space)u ', ' (space)x ', ' (space)X ', ' (space)c ' , ' (space)p ', ' (space)s '
#include <stdio.h>
int main(void)
{
printf("================= Test 'space' =================\n");
printf("% u\n", 10);
printf("%u\n", 10);
return (0);
}
C
볡μ¬
3) ' 0(number)c ', ' 0(number)p ', ' 0(number)s '
#include <stdio.h>
int main(void)
{
printf("================= Test '0' =================\n");
printf("%05s\n", "A"); // c, p, s
printf("%s\n", "A"); // c, p, s
return (0);
}
C
볡μ¬
4) ' .(number)p ', ' .(number)c '
#include <stdio.h>
int main(void)
{
printf("================= Test 'precision' =================\n");
printf("%.5p", "ABCDEFG");
return (0);
}
C
볡μ¬