ft_printf

Ji Woo Lee·2021년 1월 7일
3

Objectives

int ft_printf(const char *, ...)

  • Without buffer management
  • cspdiuxX%
  • flags will be only contain -0.*

What to know

Variable argument

  • #include "stdarg.h"
  • When you want to have function which can take variable number of arguments.
  • The last argument of a function (...) will be variable arguments.

va_list ap;

  • Need va_list type pointer to read arguments stored in stack.

va_start(va_list ap, last);

  • Initializes ap, which can be passed to va_arg() for each argument to be passed.
  • Each call to va_start must be matched by a call to va_end(), from within the same function.
  • The parameter last is the name of last parameter before the variable argument list.

va_arg(va_list ap, type)

  • The parameter ap is initialized by va_start.
  • Each call to va_arg modifies ap so that next call returns the next argument.
  • The parameter type is a type name of value that ap points.

    char c = va_arg(ap, int);
    char *s = va_arg(ap, char *);
    long long p = va_arg(ap, long long);
    int di = va_arg(ap, int);
    unsigned int uxX = va_arg(ap, unsigned int);

    • If you pass integral value with conversion rank smaller than int (e.g. char, bool, or short), it will be converted to int.

va_end(va_list ap);

  • Signals that there are no further arguments, and ap will be invalidated.

Basic format of ft_printf

%[flags][width][.precision]type

Flags

  • Default is right adjustment of the output with blank-padding.

-

  • Left adjustment of the output.

0

  • Zero-padding
  • '-' overrides '0' if both are used.

Width

  • An optional digit string specifying a field width.
  • If the output string has fewer bytes than the field width, it will be blank-padded on the left (default) to make up the field width.
  • * will read variable argument.

Precision

  • Optional period, '.', followed by an optional digit string specifying the maximum number of bytes to be printed from a string.
  • If the digit string is missing, the precision is treated as zero. ( . == .0)
  • * will read variable argument.
  • Negative precision is treated as no precision.
  • char type and pointer type do not take precision.
    -> 출력을 멈추고 -1 을 리턴하게 구현함.

Apply precision first, then compare with width.

Implementation

  • A return value of ft_printf is the number of characters printed.
    -> Used global variable g_count for easier approach.

Set structure

typedef struct s_option
{
    int flag_minus;
    int flag_zero;
    int width;
    int dot;	     // to know if there is precision
    int precision;   // initially set as -1 instead of 0
    int flag_pre_va; // if precision is a variable argument
    int num_m;	     // is number negative?
    char type;
 } t_option;
  • Used structure to hold several data items of the same kind.
  • Precision is initially set as -1 because zero precision and negative precision (which is considered as no precision) are different.
  • flag_pre_va is for distinguishing certain cases when obtaining precision from variable argument as -1.
    -> printf("%.d\n", 0) => $
    -> printf("%.*d\n", -1, 0) => 0$
  • Returns last pointer to main function.

Put in array

  • Each type has quite different formatting based on flag, precision, and width.
  • Divided into three functions based on where to pad: left_blank, left_zero, and right_blank.
  • Malloc final array to be printed.
  • Print array and increase g_count.
  • Free array.

What to be careful

  • Know each type has different approach
    -> When handling with diuxX, precision length only matters when it is longer than diuxX. (Will be zero padded)
    -> S will be cut when precision length is smaller.
  • Know special cases such as NULL and error.

0개의 댓글