mirror of
https://github.com/DavidGailleton/42-ft_printf.git
synced 2026-11-01 11:42:03 +01:00
Merge mandatory and bonus into a single ft_printf, fix edge cases, add README
- Use the flag-aware implementation for both make and make bonus
(bonus/ moved to src/, _bonus suffix dropped, bonus rule = all)
- Do not treat zero-length output (%s with "", %.0d with 0) as an error
- Return -1 without printing when a % has no conversion ("abc%", "%5")
- Keep field width with '#', '+' and ' '; ignore '0' with '-'
- Fix '#' prefix on zero, '+'/' ' with zero padding, INT_MIN negation UB
- Add README.md required by the subject
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b620f5ecdb
commit
c8a9ee10cf
24 files changed
+607
-677
No files matched your search
@@ -1,9 +1,7 @@
|
|||||||
NAME= libftprintf.a
|
NAME= libftprintf.a
|
||||||
LIBFT= $(BUILD_DIR)/libft.a
|
LIBFT= $(BUILD_DIR)/libft.a
|
||||||
BONUS= $(BUILD_DIR)/libftprintf_bonus.a
|
|
||||||
|
|
||||||
SRC_DIR= src
|
SRC_DIR= src
|
||||||
B_SRC_DIR= bonus
|
|
||||||
INC_DIR= include
|
INC_DIR= include
|
||||||
LIBFT_DIR= libft
|
LIBFT_DIR= libft
|
||||||
BUILD_DIR= .build
|
BUILD_DIR= .build
|
||||||
@@ -16,25 +14,13 @@ SRC= $(SRC_DIR)/ft_printf.c \
|
|||||||
$(SRC_DIR)/print_pointer.c \
|
$(SRC_DIR)/print_pointer.c \
|
||||||
$(SRC_DIR)/print_str.c \
|
$(SRC_DIR)/print_str.c \
|
||||||
$(SRC_DIR)/print_unsigned.c \
|
$(SRC_DIR)/print_unsigned.c \
|
||||||
|
$(SRC_DIR)/ft_create_arg.c \
|
||||||
B_SRC= $(B_SRC_DIR)/ft_printf_bonus.c \
|
$(SRC_DIR)/ft_main_arg.c \
|
||||||
$(B_SRC_DIR)/ft_putnbr_base_bonus.c \
|
$(SRC_DIR)/ft_parsing.c \
|
||||||
$(B_SRC_DIR)/print_char_bonus.c \
|
$(SRC_DIR)/utils_flag.c
|
||||||
$(B_SRC_DIR)/print_hex_bonus.c \
|
|
||||||
$(B_SRC_DIR)/print_number_bonus.c \
|
|
||||||
$(B_SRC_DIR)/print_pointer_bonus.c \
|
|
||||||
$(B_SRC_DIR)/print_str_bonus.c \
|
|
||||||
$(B_SRC_DIR)/print_unsigned_bonus.c \
|
|
||||||
$(B_SRC_DIR)/ft_create_arg_bonus.c \
|
|
||||||
$(B_SRC_DIR)/ft_main_arg_bonus.c \
|
|
||||||
$(B_SRC_DIR)/ft_parsing_bonus.c \
|
|
||||||
$(B_SRC_DIR)/utils_flag_bonus.c
|
|
||||||
|
|
||||||
|
|
||||||
OBJ= $(SRC:%.c=$(BUILD_DIR)/%.o)
|
OBJ= $(SRC:%.c=$(BUILD_DIR)/%.o)
|
||||||
B_OBJ= $(B_SRC:%.c=$(BUILD_DIR)/%.o)
|
|
||||||
DEP= $(SRC:%.c=$(BUILD_DIR)/%.d)
|
DEP= $(SRC:%.c=$(BUILD_DIR)/%.d)
|
||||||
B_DEP= $(B_SRC:%.c=$(BUILD_DIR)/%.d)
|
|
||||||
|
|
||||||
CC= cc
|
CC= cc
|
||||||
CFLAGS= -Wall -Wextra -Werror -I$(INC_DIR) -I$(LIBFT_DIR) -MMD -MP
|
CFLAGS= -Wall -Wextra -Werror -I$(INC_DIR) -I$(LIBFT_DIR) -MMD -MP
|
||||||
@@ -42,8 +28,7 @@ AR= ar rcs
|
|||||||
|
|
||||||
all: $(NAME)
|
all: $(NAME)
|
||||||
|
|
||||||
bonus: $(BONUS)
|
bonus: all
|
||||||
cp $(BONUS) $(NAME)
|
|
||||||
|
|
||||||
$(NAME): $(OBJ) $(LIBFT)
|
$(NAME): $(OBJ) $(LIBFT)
|
||||||
cp $(LIBFT) $(NAME)
|
cp $(LIBFT) $(NAME)
|
||||||
@@ -57,20 +42,16 @@ $(LIBFT):
|
|||||||
$(MAKE) -C $(LIBFT_DIR)
|
$(MAKE) -C $(LIBFT_DIR)
|
||||||
cp $(LIBFT_DIR)/libft.a $(LIBFT)
|
cp $(LIBFT_DIR)/libft.a $(LIBFT)
|
||||||
|
|
||||||
$(BONUS): $(B_OBJ) $(LIBFT)
|
|
||||||
cp $(LIBFT) $(BONUS)
|
|
||||||
$(AR) $(BONUS) $(B_OBJ)
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(OBJ) $(DEP) $(B_OBJ) $(B_DEP)
|
rm -f $(OBJ) $(DEP)
|
||||||
$(MAKE) -C $(LIBFT_DIR) clean
|
$(MAKE) -C $(LIBFT_DIR) clean
|
||||||
|
|
||||||
fclean: clean
|
fclean: clean
|
||||||
rm -f $(NAME) $(BONUS) $(LIBFT)
|
rm -f $(NAME) $(LIBFT)
|
||||||
$(MAKE) -C $(LIBFT_DIR) fclean
|
$(MAKE) -C $(LIBFT_DIR) fclean
|
||||||
|
|
||||||
re: fclean all
|
re: fclean all
|
||||||
|
|
||||||
-include $(DEP) $(B_DEP)
|
-include $(DEP)
|
||||||
|
|
||||||
.PHONY: all clean fclean re bonus
|
.PHONY: all clean fclean re bonus
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
*This project has been created as part of the 42 curriculum by dgaillet.*
|
||||||
|
|
||||||
|
# ft_printf
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
`ft_printf` is a reimplementation of the libc `printf()` function, packaged as a
|
||||||
|
static library (`libftprintf.a`). The goal of the project is to learn how
|
||||||
|
variadic functions work in C (`va_start`, `va_arg`, `va_end`) and to build
|
||||||
|
code that is easy to extend with new conversions and flags.
|
||||||
|
|
||||||
|
```c
|
||||||
|
int ft_printf(const char *format, ...);
|
||||||
|
```
|
||||||
|
|
||||||
|
It writes to standard output and returns the number of characters it printed.
|
||||||
|
It returns `-1` on a write error or an invalid format.
|
||||||
|
|
||||||
|
### Supported conversions (mandatory)
|
||||||
|
|
||||||
|
| Conversion | Output |
|
||||||
|
|---|---|
|
||||||
|
| `%c` | a single character |
|
||||||
|
| `%s` | a string (`(null)` for a `NULL` pointer) |
|
||||||
|
| `%p` | a pointer in hexadecimal, with a `0x` prefix (`(nil)` for `NULL`) |
|
||||||
|
| `%d` / `%i` | a signed decimal integer |
|
||||||
|
| `%u` | an unsigned decimal integer |
|
||||||
|
| `%x` / `%X` | an unsigned integer in lowercase / uppercase hexadecimal |
|
||||||
|
| `%%` | a literal `%` |
|
||||||
|
|
||||||
|
### Supported flags (bonus)
|
||||||
|
|
||||||
|
The same implementation handles both the mandatory conversions and the bonus
|
||||||
|
flags, so there is only one version of `ft_printf`.
|
||||||
|
|
||||||
|
|
||||||
|
- Minimum field width, for example `%10d`
|
||||||
|
- `-`: left-justify within the field
|
||||||
|
- `0`: pad numbers with zeros (ignored when `-` or a precision is given)
|
||||||
|
- `.`: precision (minimum digits for numbers, maximum characters for `%s`)
|
||||||
|
- `#`: `0x` / `0X` prefix for non-zero `%x` / `%X`
|
||||||
|
- `+`: always print a sign for signed numbers
|
||||||
|
- ` ` (space): print a space in front of positive signed numbers
|
||||||
|
|
||||||
|
Any combination of these flags behaves like glibc's `printf`.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
### Compilation
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make # builds libftprintf.a (conversions and flags)
|
||||||
|
make bonus # same as make: the bonus is built into the library
|
||||||
|
make clean # removes object files
|
||||||
|
make fclean # removes object files and libraries
|
||||||
|
make re # fclean + all
|
||||||
|
```
|
||||||
|
|
||||||
|
The `Makefile` first builds `libft` with its own `Makefile`, then adds the
|
||||||
|
`ft_printf` objects to a copy of `libft.a`. This way, `libftprintf.a`
|
||||||
|
contains everything it needs.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "ft_printf.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = ft_printf("Hello %s, you are %d years old (%#x)\n", "Bob", 42, 42);
|
||||||
|
ft_printf("%d characters printed\n", len);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cc main.c -Iinclude -L. -lftprintf -o demo && ./demo
|
||||||
|
```
|
||||||
|
|
||||||
|
## Algorithm and data structures
|
||||||
|
|
||||||
|
### Main loop
|
||||||
|
|
||||||
|
Before printing anything, `ft_printf` checks the whole format string with
|
||||||
|
`ft_check_format`. If a `%` is not followed by a conversion (for example,
|
||||||
|
`"abc%"` or `"%5"`), it returns `-1` without writing anything, like glibc.
|
||||||
|
This is not buffering: once the format is valid, output is still written as
|
||||||
|
soon as it is ready, as the subject requires.
|
||||||
|
|
||||||
|
`ft_printf` then reads the format string one character at a time:
|
||||||
|
|
||||||
|
1. An ordinary character is written right away with `write`.
|
||||||
|
2. A `%` starts a conversion specifier. The specifier is parsed into a
|
||||||
|
`t_arg` structure, printed by the matching `print_*` function, and then
|
||||||
|
skipped in the format string.
|
||||||
|
3. Every printing function returns how many characters it wrote, and
|
||||||
|
`ft_printf` adds them up.
|
||||||
|
|
||||||
|
### Data structure
|
||||||
|
|
||||||
|
Each conversion is described by a `t_arg` structure, which is allocated for
|
||||||
|
that conversion and freed once it has been printed:
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct s_arg
|
||||||
|
{
|
||||||
|
char arg; /* conversion character: c s p d i u x X % */
|
||||||
|
int padding; /* minimum field width */
|
||||||
|
int minus; /* '-' flag: width for left justification */
|
||||||
|
int zero; /* '0' flag: width to fill with zeros */
|
||||||
|
int dot; /* precision */
|
||||||
|
int hash; /* '#' flag */
|
||||||
|
int space; /* ' ' flag */
|
||||||
|
int plus; /* '+' flag */
|
||||||
|
} t_arg;
|
||||||
|
```
|
||||||
|
|
||||||
|
Every field starts at `-1`, meaning "not set". This keeps "not given" (`-1`)
|
||||||
|
separate from "given as zero" (`0`), which matters for things like `%.0d`.
|
||||||
|
A plain conversion such as `%d` leaves every flag at `-1`, so the mandatory
|
||||||
|
conversions follow the same path with no special case.
|
||||||
|
|
||||||
|
### Processing a conversion
|
||||||
|
|
||||||
|
1. **Find the conversion** (`ft_main_arg`): skip flag, width and precision
|
||||||
|
characters (`-0# +.` and digits). The first other character is the
|
||||||
|
conversion.
|
||||||
|
2. **Parse** (`ft_parsing`): walk the specifier and fill in the `t_arg`.
|
||||||
|
Each flag stores the number written right after it, the precision is read
|
||||||
|
after the `.`, and the width is read backwards from the `.` or the
|
||||||
|
conversion character. If `-` is present, `0` is ignored, as the C standard
|
||||||
|
requires.
|
||||||
|
3. **Print** (`print_*`): `ft_print_arg_flags` fetches the argument with
|
||||||
|
`va_arg` using the matching type. Each `print_*` function works out its own
|
||||||
|
padding, in this order: leading spaces, then the sign or `0x` prefix, then
|
||||||
|
zeros (from the `0` flag or the precision), then the digits. A trailing
|
||||||
|
`-` field is padded with spaces at the end, in `ft_print_arg_flags`.
|
||||||
|
4. **Skip** (`ft_to_skip`): move the format index past the whole specifier.
|
||||||
|
|
||||||
|
### Printing numbers
|
||||||
|
|
||||||
|
Numbers are printed by the recursive functions `ft_putnbr_base` (for
|
||||||
|
`unsigned int`) and `ft_putnbr_base_ll` (for 64-bit pointers). They first
|
||||||
|
recurse on `nbr / base_size`, then write `base[nbr % base_size]`, so the digits
|
||||||
|
come out in the right order without a temporary buffer. The same functions
|
||||||
|
print decimal, lowercase hexadecimal and uppercase hexadecimal, just by
|
||||||
|
changing the base string. A negative `int` is turned into its absolute value
|
||||||
|
as an `unsigned int` before printing, so `INT_MIN` works without overflow.
|
||||||
|
|
||||||
|
### Error handling
|
||||||
|
|
||||||
|
On failure, every printing function returns a negative value (`-1` from
|
||||||
|
`write`, or a large negative sentinel from the helpers). After each step,
|
||||||
|
`ft_printf` checks whether the running total went down. If it did,
|
||||||
|
`ft_printf` stops and returns `-1`. A conversion that prints nothing, such as
|
||||||
|
`%s` with `""` or `%.0d` with `0`, adds 0 and is not an error.
|
||||||
|
|
||||||
|
### Why this design
|
||||||
|
|
||||||
|
This layout has one small parser and one function per conversion. Supporting a
|
||||||
|
new flag means adding a field to `t_arg`, a case in the parser and the related
|
||||||
|
padding logic, without changing the main loop.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- [`printf(3)` man page](https://man7.org/linux/man-pages/man3/printf.3.html):
|
||||||
|
how flags, width and precision behave
|
||||||
|
- [`stdarg(3)` man page](https://man7.org/linux/man-pages/man3/stdarg.3.html):
|
||||||
|
variadic functions
|
||||||
|
- [cppreference: `printf`](https://en.cppreference.com/w/c/io/fprintf):
|
||||||
|
the full conversion specification
|
||||||
|
- The C standard (ISO/IEC 9899), section 7.21.6.1, on the `fprintf` function
|
||||||
|
- The 42 Norm, for code style
|
||||||
|
|
||||||
|
### Use of AI
|
||||||
|
|
||||||
|
The implementation was written by hand. An AI assistant (Claude) was used at
|
||||||
|
the end of the project to:
|
||||||
|
|
||||||
|
- **Review the code against the subject and the real `printf`.** It wrote a
|
||||||
|
test program that compares the output and return value of `ft_printf` with
|
||||||
|
glibc's `printf` on many edge cases (empty strings, `NULL`, `INT_MIN`,
|
||||||
|
zero precision, flag combinations, trailing `%`). It also ran the tests with
|
||||||
|
AddressSanitizer and UBSan.
|
||||||
|
- **Fix the bugs it found, with minimal changes.** These were: empty output
|
||||||
|
being treated as an error, field width being lost when combined with
|
||||||
|
`#`/`+`/space, `0` not being ignored with `-`, the `#` prefix on zero, and
|
||||||
|
signed overflow on `INT_MIN`.
|
||||||
|
- **Merge the mandatory and bonus implementations into a single version**, and
|
||||||
|
check the format before printing so an incomplete `%` returns `-1` without
|
||||||
|
any output.
|
||||||
|
- **Write this README.**
|
||||||
|
|
||||||
|
Every change was reviewed and understood before it was kept.
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* ft_printf_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 10:54:03 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 14:59:50 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int ft_print_arg_flags(t_arg *arg, va_list args)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
if (arg->arg == 'c')
|
|
||||||
count += print_char(arg, va_arg(args, int));
|
|
||||||
else if (arg->arg == 's')
|
|
||||||
count += print_str(arg, va_arg(args, char *));
|
|
||||||
else if (arg->arg == 'p')
|
|
||||||
count += print_pointer(arg, va_arg(args, long long));
|
|
||||||
else if (arg->arg == 'd' || arg->arg == 'i')
|
|
||||||
count += print_number(arg, va_arg(args, int));
|
|
||||||
else if (arg->arg == 'u')
|
|
||||||
count += print_unsigned(arg, va_arg(args, unsigned int));
|
|
||||||
else if (arg->arg == 'x' || arg->arg == 'X')
|
|
||||||
count += print_hex(arg, va_arg(args, unsigned int));
|
|
||||||
if (count < 0)
|
|
||||||
return (-1);
|
|
||||||
count += print_chars(arg->minus - count, ' ');
|
|
||||||
if (count < 0)
|
|
||||||
return (-1);
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ft_print_arg(char *str, va_list args)
|
|
||||||
{
|
|
||||||
t_arg *arg;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
arg = ft_parsing(str);
|
|
||||||
if (!arg)
|
|
||||||
return (-1);
|
|
||||||
if (arg->arg == '%')
|
|
||||||
count = write(1, "%", 1);
|
|
||||||
else
|
|
||||||
count = ft_print_arg_flags(arg, args);
|
|
||||||
free(arg);
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ft_to_skip(char *str)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
while (!(*str == 'c' || *str == 's' || *str == 'p' || *str == 'd'
|
|
||||||
|| *str == 'i' || *str == 'u' || *str == 'x' || *str == 'X'
|
|
||||||
|| *str == '%') && *str)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
str++;
|
|
||||||
}
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int handle_arg(const char *s, va_list args, int *i)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
(*i)++;
|
|
||||||
n = ft_print_arg((char *)&s[*i], args);
|
|
||||||
*i += ft_to_skip((char *)&s[*i]);
|
|
||||||
return (n);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ft_printf(const char *first_arg, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
int nb_print;
|
|
||||||
int i;
|
|
||||||
int temp;
|
|
||||||
|
|
||||||
if (!first_arg)
|
|
||||||
return (-1);
|
|
||||||
nb_print = 0;
|
|
||||||
i = -1;
|
|
||||||
va_start(args, first_arg);
|
|
||||||
while (first_arg[++i])
|
|
||||||
{
|
|
||||||
temp = nb_print;
|
|
||||||
if (first_arg[i] == '%' && first_arg[i + 1])
|
|
||||||
nb_print += handle_arg(first_arg, args, &i);
|
|
||||||
else if (first_arg[i] != '%')
|
|
||||||
nb_print += write(1, &first_arg[i], 1);
|
|
||||||
if (temp >= nb_print)
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
va_end(args);
|
|
||||||
return (nb_print);
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* ft_putnbr_base_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 12:16:44 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 15:04:59 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "libft.h"
|
|
||||||
|
|
||||||
static int ft_putnbr_base_extra(unsigned int nbr, char *base, int base_size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char temp;
|
|
||||||
|
|
||||||
if (nbr == 0)
|
|
||||||
return (0);
|
|
||||||
i = 1 + ft_putnbr_base_extra(nbr / base_size, base, base_size);
|
|
||||||
temp = base[nbr % base_size];
|
|
||||||
if (write(1, &temp, 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ft_putnbr_base(unsigned int nbr, char *base, int base_size, int limit)
|
|
||||||
{
|
|
||||||
char temp;
|
|
||||||
|
|
||||||
if (nbr == 0 && limit != 0)
|
|
||||||
{
|
|
||||||
temp = base[0];
|
|
||||||
if (write(1, &temp, 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (ft_putnbr_base_extra(nbr, base, base_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ft_putnbr_base_ll_extra(unsigned long long nbr, char *base,
|
|
||||||
int base_size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char temp;
|
|
||||||
|
|
||||||
if (nbr == 0)
|
|
||||||
return (0);
|
|
||||||
i = 1 + ft_putnbr_base_ll_extra(nbr / base_size, base, base_size);
|
|
||||||
temp = base[nbr % base_size];
|
|
||||||
if (write(1, &temp, 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (i);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ft_putnbr_base_ll(unsigned long long nbr, char *base, int base_size)
|
|
||||||
{
|
|
||||||
char temp;
|
|
||||||
|
|
||||||
if (nbr == 0)
|
|
||||||
{
|
|
||||||
temp = base[0];
|
|
||||||
if (write(1, &temp, 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
return (ft_putnbr_base_ll_extra(nbr, base, base_size));
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* print_char_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 11:56:36 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 15:31:35 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
int print_char(t_arg *arg, char c)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
count += print_chars(arg->padding - 1, ' ');
|
|
||||||
if (!arg->minus && arg->zero)
|
|
||||||
count += print_chars(arg->zero - 1, ' ');
|
|
||||||
if (write(1, &c, 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
count++;
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* print_hex_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 12:06:35 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 15:39:21 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int padding_size(t_arg *arg, unsigned int nbr)
|
|
||||||
{
|
|
||||||
int padding;
|
|
||||||
int nbr_size;
|
|
||||||
|
|
||||||
if (arg->padding < 0)
|
|
||||||
return (0);
|
|
||||||
padding = arg->padding;
|
|
||||||
nbr_size = nbr_size_base(nbr, 16);
|
|
||||||
if (arg->dot > nbr_size || (arg->dot == 0 && !nbr))
|
|
||||||
nbr_size = arg->dot;
|
|
||||||
padding = padding - nbr_size;
|
|
||||||
return (padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int print_nb_flags(t_arg *arg, unsigned int nbr)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int padding;
|
|
||||||
|
|
||||||
padding = padding_size(arg, nbr);
|
|
||||||
count = 0;
|
|
||||||
if (arg->dot >= 0 || arg->zero < 0)
|
|
||||||
count += print_chars(padding, ' ');
|
|
||||||
if (arg->dot >= 0)
|
|
||||||
arg->zero = -1;
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int print_hex_zero(t_arg *arg)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
if (write(1, "0", 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
count++;
|
|
||||||
count += print_chars(arg->zero - 1, '0');
|
|
||||||
count += print_chars(arg->dot - 1, '0');
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int print_hex(t_arg *arg, unsigned int nbr)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int temp;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
count += print_nb_flags(arg, nbr);
|
|
||||||
if (nbr == 0 && arg->dot)
|
|
||||||
count += print_hex_zero(arg);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
temp = count;
|
|
||||||
if (arg->hash > 0 && arg->arg == 'X')
|
|
||||||
count += write(1, "0X", 2);
|
|
||||||
else if (arg->hash > 0)
|
|
||||||
count += write(1, "0x", 2);
|
|
||||||
if (temp > count)
|
|
||||||
return (-10000);
|
|
||||||
count += print_chars(arg->zero - count - nbr_size_base(nbr, 16), '0');
|
|
||||||
count += print_chars(arg->dot - nbr_size_base(nbr, 16), '0');
|
|
||||||
if (arg->arg == 'X')
|
|
||||||
count += ft_putnbr_base(nbr, "0123456789ABCDEF", 16, arg->dot);
|
|
||||||
else
|
|
||||||
count += ft_putnbr_base(nbr, "0123456789abcdef", 16, arg->dot);
|
|
||||||
}
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* print_number_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 17:08:15 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int padding_size(int space, int plus, t_arg *arg, int nbr)
|
|
||||||
{
|
|
||||||
int padding;
|
|
||||||
int nbr_size;
|
|
||||||
unsigned int temp;
|
|
||||||
|
|
||||||
if (arg->padding < 0)
|
|
||||||
return (0);
|
|
||||||
padding = arg->padding - space - plus;
|
|
||||||
if (nbr < 0)
|
|
||||||
{
|
|
||||||
temp = nbr * -1;
|
|
||||||
nbr_size = nbr_size_base(temp, 10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nbr_size = nbr_size_base(nbr, 10);
|
|
||||||
if (arg->dot > nbr_size || (arg->dot == 0 && !nbr))
|
|
||||||
nbr_size = arg->dot;
|
|
||||||
padding = padding - nbr_size;
|
|
||||||
if (nbr < 0)
|
|
||||||
padding--;
|
|
||||||
return (padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int print_nb_flags(t_arg *arg, int nbr)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int space;
|
|
||||||
int padding;
|
|
||||||
int plus;
|
|
||||||
|
|
||||||
if (arg->plus >= 0 && nbr >= 0)
|
|
||||||
plus = 1;
|
|
||||||
else
|
|
||||||
plus = 0;
|
|
||||||
if (arg->plus >= 0 || arg->space < 0)
|
|
||||||
space = 0;
|
|
||||||
else
|
|
||||||
space = 1;
|
|
||||||
padding = padding_size(space, plus, arg, nbr);
|
|
||||||
count = 0;
|
|
||||||
if (arg->dot >= 0 || arg->zero < 0)
|
|
||||||
count += print_chars(padding, ' ');
|
|
||||||
if (nbr >= 0)
|
|
||||||
count += print_chars(space, ' ');
|
|
||||||
count += print_chars(plus, '+');
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int print_number(t_arg *arg, int nbr)
|
|
||||||
{
|
|
||||||
unsigned int p_nbr;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
p_nbr = nbr;
|
|
||||||
count += print_nb_flags(arg, nbr);
|
|
||||||
if (nbr < 0)
|
|
||||||
{
|
|
||||||
if (write(1, "-", 1) < 0)
|
|
||||||
return (-10000);
|
|
||||||
count++;
|
|
||||||
p_nbr = nbr * -1;
|
|
||||||
if (arg->dot < 0)
|
|
||||||
count += print_chars(arg->zero - nbr_size_base(p_nbr, 10) - 1, '0');
|
|
||||||
}
|
|
||||||
else if (arg->dot < 0)
|
|
||||||
count += print_chars(arg->zero - nbr_size_base(p_nbr, 10), '0');
|
|
||||||
count += print_chars(arg->dot - nbr_size_base(p_nbr, 10), '0');
|
|
||||||
count += ft_putnbr_base(p_nbr, "0123456789", 10, arg->dot);
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* print_pointer_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 12:19:16 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 15:46:51 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include "libft.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
int print_pointer(t_arg *arg, unsigned long long p)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
count += print_chars(arg->padding - 5, ' ');
|
|
||||||
if (write(1, "(nil)", 5) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (5 + count);
|
|
||||||
}
|
|
||||||
count += print_chars(arg->padding - nbr_size_base(p, 16) - 2, ' ');
|
|
||||||
if (write(1, "0x", 2) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (count + 2 + ft_putnbr_base_ll(p, "0123456789abcdef", 16));
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* print_str_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 12:02:03 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 15:32:08 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include "libft.h"
|
|
||||||
|
|
||||||
int print_str(t_arg *arg, char *str)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
if (!str)
|
|
||||||
{
|
|
||||||
if (arg->dot < 6 && arg->dot >= 0)
|
|
||||||
return (print_chars(arg->padding, ' '));
|
|
||||||
if (arg->padding > 6)
|
|
||||||
count += print_chars(arg->padding - 6, ' ');
|
|
||||||
if (write(1, "(null)", 6) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (count + 6);
|
|
||||||
}
|
|
||||||
if (arg->dot > (int)ft_strlen(str) || arg->dot < 0)
|
|
||||||
arg->dot = ft_strlen(str);
|
|
||||||
if (arg->padding > 0)
|
|
||||||
count += print_chars(arg->padding - arg->dot, ' ');
|
|
||||||
else if (!str[0] && arg->space > 0)
|
|
||||||
return (write(1, " ", 1));
|
|
||||||
if (write(1, str, arg->dot) < 0)
|
|
||||||
return (-10000);
|
|
||||||
return (count + arg->dot);
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* print_unsigned_bonus.c :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 14:22:44 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
static int padding_size(t_arg *arg, unsigned int nbr)
|
|
||||||
{
|
|
||||||
int padding;
|
|
||||||
int nbr_size;
|
|
||||||
|
|
||||||
if (arg->padding < 0)
|
|
||||||
return (0);
|
|
||||||
padding = arg->padding;
|
|
||||||
nbr_size = nbr_size_base(nbr, 10);
|
|
||||||
if (arg->dot > nbr_size || (arg->dot == 0 && !nbr))
|
|
||||||
nbr_size = arg->dot;
|
|
||||||
padding = padding - nbr_size;
|
|
||||||
return (padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int print_nb_flags(t_arg *arg, unsigned int nbr)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
int padding;
|
|
||||||
|
|
||||||
padding = padding_size(arg, nbr);
|
|
||||||
count = 0;
|
|
||||||
if (arg->dot >= 0 || arg->zero < 0)
|
|
||||||
count += print_chars(padding, ' ');
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int print_unsigned(t_arg *arg, unsigned int nbr)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
count += print_nb_flags(arg, nbr);
|
|
||||||
if (arg->dot < 0)
|
|
||||||
count += print_chars(arg->zero - nbr_size_base(nbr, 10), '0');
|
|
||||||
count += print_chars(arg->dot - nbr_size_base(nbr, 10), '0');
|
|
||||||
count += ft_putnbr_base(nbr, "0123456789", 10, arg->dot);
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
+31
-9
@@ -6,23 +6,45 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 10:52:23 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 10:52:23 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/17 12:47:41 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 12:10:56 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef FT_PRINTF_H
|
#ifndef FT_PRINTF_H
|
||||||
# define FT_PRINTF_H
|
# define FT_PRINTF_H
|
||||||
|
|
||||||
int ft_printf(const char *first_arg, ...) __attribute__((format(printf, 1, 2)));
|
typedef struct s_arg
|
||||||
|
{
|
||||||
|
char arg;
|
||||||
|
int padding;
|
||||||
|
int minus;
|
||||||
|
int zero;
|
||||||
|
int dot;
|
||||||
|
int hash;
|
||||||
|
int space;
|
||||||
|
int plus;
|
||||||
|
} t_arg;
|
||||||
|
|
||||||
|
int ft_printf(const char *first_arg, ...) __attribute__((format(printf,
|
||||||
|
1, 2)));
|
||||||
int ft_printf(const char *first_arg, ...);
|
int ft_printf(const char *first_arg, ...);
|
||||||
|
|
||||||
int ft_putnbr_base(unsigned long long nbr, char *base, int base_size);
|
int ft_putnbr_base_ll(unsigned long long nbr, char *base,
|
||||||
|
int base_size);
|
||||||
|
int ft_putnbr_base(unsigned int nbr, char *base, int base_size,
|
||||||
|
int limit);
|
||||||
|
char ft_main_arg(char *str);
|
||||||
|
int ft_check_format(const char *str);
|
||||||
|
t_arg *ft_create_arg(void);
|
||||||
|
t_arg *ft_parsing(char *str);
|
||||||
|
int print_chars(int nb, char c);
|
||||||
|
int nbr_size_base(unsigned long long nb, int base_size);
|
||||||
|
|
||||||
int print_char(char c);
|
int print_char(t_arg *arg, char c);
|
||||||
int print_str(char *str);
|
int print_str(t_arg *arg, char *str);
|
||||||
int print_pointer(unsigned long long p);
|
int print_pointer(t_arg *arg, unsigned long long p);
|
||||||
int print_number(int nbr);
|
int print_number(t_arg *arg, int nbr);
|
||||||
int print_unsigned(unsigned int nbr);
|
int print_unsigned(t_arg *arg, unsigned int nbr);
|
||||||
int print_hex(unsigned long long p, int upper);
|
int print_hex(t_arg *arg, unsigned int nbr);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* ft_printf_bonus.h :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/11/17 10:52:23 by dgaillet #+# #+# */
|
|
||||||
/* Updated: 2025/11/21 12:10:56 by dgaillet ### ########lyon.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#ifndef FT_PRINTF_BONUS_H
|
|
||||||
# define FT_PRINTF_BONUS_H
|
|
||||||
|
|
||||||
typedef struct s_arg
|
|
||||||
{
|
|
||||||
char arg;
|
|
||||||
int padding;
|
|
||||||
int minus;
|
|
||||||
int zero;
|
|
||||||
int dot;
|
|
||||||
int hash;
|
|
||||||
int space;
|
|
||||||
int plus;
|
|
||||||
} t_arg;
|
|
||||||
|
|
||||||
int ft_printf(const char *first_arg, ...) __attribute__((format(printf,
|
|
||||||
1, 2)));
|
|
||||||
int ft_printf(const char *first_arg, ...);
|
|
||||||
|
|
||||||
int ft_putnbr_base_ll(unsigned long long nbr, char *base,
|
|
||||||
int base_size);
|
|
||||||
int ft_putnbr_base(unsigned int nbr, char *base, int base_size,
|
|
||||||
int limit);
|
|
||||||
char ft_main_arg(char *str);
|
|
||||||
t_arg *ft_create_arg(void);
|
|
||||||
t_arg *ft_parsing(char *str);
|
|
||||||
int print_chars(int nb, char c);
|
|
||||||
int nbr_size_base(unsigned long long nb, int base_size);
|
|
||||||
|
|
||||||
int print_char(t_arg *arg, char c);
|
|
||||||
int print_str(t_arg *arg, char *str);
|
|
||||||
int print_pointer(t_arg *arg, unsigned long long p);
|
|
||||||
int print_number(t_arg *arg, int nbr);
|
|
||||||
int print_unsigned(t_arg *arg, unsigned int nbr);
|
|
||||||
int print_hex(t_arg *arg, unsigned int nbr);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* ft_create_arg_bonus.c :+: :+: :+: */
|
/* ft_create_arg.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
#include "ft_printf.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
t_arg *ft_create_arg(void)
|
t_arg *ft_create_arg(void)
|
||||||
@@ -10,21 +10,34 @@
|
|||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
static int is_main_arg(char c)
|
static int is_flag(char c)
|
||||||
{
|
{
|
||||||
if (c == 'c' || c == 's' || c == 'p' || c == 'd' || c == 'i' || c == 'u'
|
if ((c >= '0' && c <= '9') || c == '-' || c == '#' || c == ' '
|
||||||
|| c == 'x' || c == 'X' || c == '%')
|
|| c == '+' || c == '.')
|
||||||
return (1);
|
return (1);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char ft_main_arg(char *str)
|
char ft_main_arg(char *str)
|
||||||
{
|
{
|
||||||
while (*str)
|
while (*str && is_flag(*str))
|
||||||
{
|
|
||||||
if (is_main_arg(*str))
|
|
||||||
break ;
|
|
||||||
str++;
|
str++;
|
||||||
}
|
|
||||||
return (*str);
|
return (*str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ft_check_format(const char *str)
|
||||||
|
{
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
if (*str == '%')
|
||||||
|
{
|
||||||
|
str++;
|
||||||
|
while (*str && is_flag(*str))
|
||||||
|
str++;
|
||||||
|
if (!*str)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* ft_parsing_bonus.c :+: :+: :+: */
|
/* ft_parsing.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf_bonus.h"
|
#include "ft_printf.h"
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
|
|
||||||
static void get_padding(t_arg *arg, char *str)
|
static void get_padding(t_arg *arg, char *str)
|
||||||
@@ -39,15 +39,11 @@ static void ft_parse_str(t_arg *arg, char *str, char main_arg)
|
|||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
if (*str == '.')
|
if (*str == '.')
|
||||||
{
|
|
||||||
arg->dot = ft_atoi(str + 1);
|
arg->dot = ft_atoi(str + 1);
|
||||||
if (!(arg->minus >= 0 || arg->hash >= 0 || arg->space >= 0
|
if (arg->minus < 0)
|
||||||
|| arg->plus >= 0))
|
|
||||||
get_padding(arg, str);
|
|
||||||
}
|
|
||||||
else if (!(arg->minus >= 0 || arg->hash >= 0 || arg->space >= 0
|
|
||||||
|| arg->plus >= 0))
|
|
||||||
get_padding(arg, str);
|
get_padding(arg, str);
|
||||||
|
else
|
||||||
|
arg->zero = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
t_arg *ft_parsing(char *str)
|
t_arg *ft_parsing(char *str)
|
||||||
+73
-28
@@ -6,33 +6,81 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 10:54:03 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 10:54:03 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/21 14:47:19 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 14:59:50 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static int ft_print_arg(char c, va_list args)
|
static int ft_print_arg_flags(t_arg *arg, va_list args)
|
||||||
{
|
{
|
||||||
if (c == 'c')
|
int count;
|
||||||
return (print_char(va_arg(args, int)));
|
|
||||||
else if (c == 's')
|
count = 0;
|
||||||
return (print_str(va_arg(args, char *)));
|
if (arg->arg == 'c')
|
||||||
else if (c == 'p')
|
count += print_char(arg, va_arg(args, int));
|
||||||
return (print_pointer(va_arg(args, unsigned long long)));
|
else if (arg->arg == 's')
|
||||||
else if (c == 'd' || c == 'i')
|
count += print_str(arg, va_arg(args, char *));
|
||||||
return (print_number(va_arg(args, int)));
|
else if (arg->arg == 'p')
|
||||||
else if (c == 'u')
|
count += print_pointer(arg, va_arg(args, long long));
|
||||||
return (print_unsigned(va_arg(args, unsigned int)));
|
else if (arg->arg == 'd' || arg->arg == 'i')
|
||||||
else if (c == 'x')
|
count += print_number(arg, va_arg(args, int));
|
||||||
return (print_hex(va_arg(args, unsigned int), 0));
|
else if (arg->arg == 'u')
|
||||||
else if (c == 'X')
|
count += print_unsigned(arg, va_arg(args, unsigned int));
|
||||||
return (print_hex(va_arg(args, unsigned int), 1));
|
else if (arg->arg == 'x' || arg->arg == 'X')
|
||||||
else if (c == '%')
|
count += print_hex(arg, va_arg(args, unsigned int));
|
||||||
return (print_char('%'));
|
else
|
||||||
return (0);
|
return (-1);
|
||||||
|
if (count < 0)
|
||||||
|
return (-1);
|
||||||
|
count += print_chars(arg->minus - count, ' ');
|
||||||
|
if (count < 0)
|
||||||
|
return (-1);
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ft_print_arg(char *str, va_list args)
|
||||||
|
{
|
||||||
|
t_arg *arg;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
arg = ft_parsing(str);
|
||||||
|
if (!arg)
|
||||||
|
return (-1);
|
||||||
|
if (arg->arg == '%')
|
||||||
|
count = write(1, "%", 1);
|
||||||
|
else
|
||||||
|
count = ft_print_arg_flags(arg, args);
|
||||||
|
free(arg);
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ft_to_skip(char *str)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
while (!(*str == 'c' || *str == 's' || *str == 'p' || *str == 'd'
|
||||||
|
|| *str == 'i' || *str == 'u' || *str == 'x' || *str == 'X'
|
||||||
|
|| *str == '%') && *str)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_arg(const char *s, va_list args, int *i)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
(*i)++;
|
||||||
|
n = ft_print_arg((char *)&s[*i], args);
|
||||||
|
*i += ft_to_skip((char *)&s[*i]);
|
||||||
|
return (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ft_printf(const char *first_arg, ...)
|
int ft_printf(const char *first_arg, ...)
|
||||||
@@ -42,22 +90,19 @@ int ft_printf(const char *first_arg, ...)
|
|||||||
int i;
|
int i;
|
||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
if (!first_arg)
|
if (!first_arg || !ft_check_format(first_arg))
|
||||||
return (-1);
|
return (-1);
|
||||||
nb_print = 0;
|
nb_print = 0;
|
||||||
va_start(args, first_arg);
|
|
||||||
i = -1;
|
i = -1;
|
||||||
|
va_start(args, first_arg);
|
||||||
while (first_arg[++i])
|
while (first_arg[++i])
|
||||||
{
|
{
|
||||||
temp = nb_print;
|
temp = nb_print;
|
||||||
if (first_arg[i] == '%' && first_arg[i + 1] != '\0')
|
if (first_arg[i] == '%')
|
||||||
{
|
nb_print += handle_arg(first_arg, args, &i);
|
||||||
i++;
|
else
|
||||||
nb_print += ft_print_arg(first_arg[i], args);
|
|
||||||
}
|
|
||||||
else if (first_arg[i] != '%')
|
|
||||||
nb_print += write(1, &first_arg[i], 1);
|
nb_print += write(1, &first_arg[i], 1);
|
||||||
if (temp >= nb_print)
|
if (temp > nb_print)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|||||||
+46
-3
@@ -6,22 +6,65 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 12:16:44 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 12:16:44 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/21 14:49:36 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 15:04:59 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
|
|
||||||
int ft_putnbr_base(unsigned long long nbr, char *base, int base_size)
|
static int ft_putnbr_base_extra(unsigned int nbr, char *base, int base_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char temp;
|
char temp;
|
||||||
|
|
||||||
if (nbr == 0)
|
if (nbr == 0)
|
||||||
return (0);
|
return (0);
|
||||||
i = 1 + ft_putnbr_base(nbr / base_size, base, base_size);
|
i = 1 + ft_putnbr_base_extra(nbr / base_size, base, base_size);
|
||||||
temp = base[nbr % base_size];
|
temp = base[nbr % base_size];
|
||||||
if (write(1, &temp, 1) < 0)
|
if (write(1, &temp, 1) < 0)
|
||||||
return (-10000);
|
return (-10000);
|
||||||
return (i);
|
return (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ft_putnbr_base(unsigned int nbr, char *base, int base_size, int limit)
|
||||||
|
{
|
||||||
|
char temp;
|
||||||
|
|
||||||
|
if (nbr == 0 && limit != 0)
|
||||||
|
{
|
||||||
|
temp = base[0];
|
||||||
|
if (write(1, &temp, 1) < 0)
|
||||||
|
return (-10000);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (ft_putnbr_base_extra(nbr, base, base_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ft_putnbr_base_ll_extra(unsigned long long nbr, char *base,
|
||||||
|
int base_size)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char temp;
|
||||||
|
|
||||||
|
if (nbr == 0)
|
||||||
|
return (0);
|
||||||
|
i = 1 + ft_putnbr_base_ll_extra(nbr / base_size, base, base_size);
|
||||||
|
temp = base[nbr % base_size];
|
||||||
|
if (write(1, &temp, 1) < 0)
|
||||||
|
return (-10000);
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ft_putnbr_base_ll(unsigned long long nbr, char *base, int base_size)
|
||||||
|
{
|
||||||
|
char temp;
|
||||||
|
|
||||||
|
if (nbr == 0)
|
||||||
|
{
|
||||||
|
temp = base[0];
|
||||||
|
if (write(1, &temp, 1) < 0)
|
||||||
|
return (-10000);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
return (ft_putnbr_base_ll_extra(nbr, base, base_size));
|
||||||
|
}
|
||||||
+13
-3
@@ -6,13 +6,23 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 11:56:36 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 11:56:36 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/17 12:45:57 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 15:31:35 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_printf.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int print_char(char c)
|
int print_char(t_arg *arg, char c)
|
||||||
{
|
{
|
||||||
return (write(1, &c, 1));
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
count += print_chars(arg->padding - 1, ' ');
|
||||||
|
if (!arg->minus && arg->zero)
|
||||||
|
count += print_chars(arg->zero - 1, ' ');
|
||||||
|
if (write(1, &c, 1) < 0)
|
||||||
|
return (-10000);
|
||||||
|
count++;
|
||||||
|
return (count);
|
||||||
}
|
}
|
||||||
+71
-7
@@ -6,19 +6,83 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 12:06:35 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 12:06:35 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/17 12:46:47 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 15:39:21 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int print_hex(unsigned long long nbr, int upper)
|
static int padding_size(t_arg *arg, unsigned int nbr)
|
||||||
{
|
{
|
||||||
if (nbr == 0)
|
int padding;
|
||||||
return (write(1, "0", 1));
|
int nbr_size;
|
||||||
if (upper)
|
|
||||||
return (ft_putnbr_base(nbr, "0123456789ABCDEF", 16));
|
if (arg->padding < 0)
|
||||||
|
return (0);
|
||||||
|
padding = arg->padding;
|
||||||
|
nbr_size = nbr_size_base(nbr, 16);
|
||||||
|
if (arg->dot > nbr_size || (arg->dot == 0 && !nbr))
|
||||||
|
nbr_size = arg->dot;
|
||||||
|
padding = padding - nbr_size;
|
||||||
|
if (arg->hash > 0)
|
||||||
|
padding -= 2;
|
||||||
|
return (padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int print_nb_flags(t_arg *arg, unsigned int nbr)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int padding;
|
||||||
|
|
||||||
|
if (!nbr)
|
||||||
|
arg->hash = -1;
|
||||||
|
padding = padding_size(arg, nbr);
|
||||||
|
count = 0;
|
||||||
|
if (arg->dot >= 0 || arg->zero < 0)
|
||||||
|
count += print_chars(padding, ' ');
|
||||||
|
if (arg->dot >= 0)
|
||||||
|
arg->zero = -1;
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int print_hex_zero(t_arg *arg)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
if (write(1, "0", 1) < 0)
|
||||||
|
return (-10000);
|
||||||
|
count++;
|
||||||
|
count += print_chars(arg->zero - 1, '0');
|
||||||
|
count += print_chars(arg->dot - 1, '0');
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_hex(t_arg *arg, unsigned int nbr)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
count += print_nb_flags(arg, nbr);
|
||||||
|
if (nbr == 0 && arg->dot)
|
||||||
|
count += print_hex_zero(arg);
|
||||||
else
|
else
|
||||||
return (ft_putnbr_base(nbr, "0123456789abcdef", 16));
|
{
|
||||||
|
temp = count;
|
||||||
|
if (arg->hash > 0 && arg->arg == 'X')
|
||||||
|
count += write(1, "0X", 2);
|
||||||
|
else if (arg->hash > 0)
|
||||||
|
count += write(1, "0x", 2);
|
||||||
|
if (temp > count)
|
||||||
|
return (-10000);
|
||||||
|
count += print_chars(arg->zero - count - nbr_size_base(nbr, 16), '0');
|
||||||
|
count += print_chars(arg->dot - nbr_size_base(nbr, 16), '0');
|
||||||
|
if (arg->arg == 'X')
|
||||||
|
count += ft_putnbr_base(nbr, "0123456789ABCDEF", 16, arg->dot);
|
||||||
|
else
|
||||||
|
count += ft_putnbr_base(nbr, "0123456789abcdef", 16, arg->dot);
|
||||||
|
}
|
||||||
|
return (count);
|
||||||
}
|
}
|
||||||
+69
-9
@@ -6,24 +6,84 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/17 12:56:40 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 17:08:15 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int print_number(int nbr)
|
static int padding_size(int space, int plus, t_arg *arg, int nbr)
|
||||||
{
|
{
|
||||||
unsigned int p_nbr;
|
int padding;
|
||||||
|
int nbr_size;
|
||||||
|
unsigned int temp;
|
||||||
|
|
||||||
if (nbr == 0)
|
if (arg->padding < 0)
|
||||||
return (write(1, "0", 1));
|
return (0);
|
||||||
|
padding = arg->padding - space - plus;
|
||||||
if (nbr < 0)
|
if (nbr < 0)
|
||||||
{
|
{
|
||||||
write(1, "-", 1);
|
temp = (unsigned int)nbr * -1;
|
||||||
p_nbr = nbr * -1;
|
nbr_size = nbr_size_base(temp, 10);
|
||||||
return (1 + ft_putnbr_base(p_nbr, "0123456789", 10));
|
|
||||||
}
|
}
|
||||||
return (ft_putnbr_base(nbr, "0123456789", 10));
|
else
|
||||||
|
nbr_size = nbr_size_base(nbr, 10);
|
||||||
|
if (arg->dot > nbr_size || (arg->dot == 0 && !nbr))
|
||||||
|
nbr_size = arg->dot;
|
||||||
|
padding = padding - nbr_size;
|
||||||
|
if (nbr < 0)
|
||||||
|
padding--;
|
||||||
|
return (padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int print_nb_flags(t_arg *arg, int nbr)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int space;
|
||||||
|
int padding;
|
||||||
|
int plus;
|
||||||
|
|
||||||
|
if (arg->plus >= 0 && nbr >= 0)
|
||||||
|
plus = 1;
|
||||||
|
else
|
||||||
|
plus = 0;
|
||||||
|
if (arg->plus >= 0 || arg->space < 0)
|
||||||
|
space = 0;
|
||||||
|
else
|
||||||
|
space = 1;
|
||||||
|
padding = padding_size(space, plus, arg, nbr);
|
||||||
|
count = 0;
|
||||||
|
if (arg->dot >= 0 || arg->zero < 0)
|
||||||
|
count += print_chars(padding, ' ');
|
||||||
|
if (nbr >= 0)
|
||||||
|
count += print_chars(space, ' ');
|
||||||
|
count += print_chars(plus, '+');
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_number(t_arg *arg, int nbr)
|
||||||
|
{
|
||||||
|
unsigned int p_nbr;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
p_nbr = nbr;
|
||||||
|
if (nbr >= 0 && (arg->plus >= 0 || arg->space >= 0))
|
||||||
|
arg->zero--;
|
||||||
|
count += print_nb_flags(arg, nbr);
|
||||||
|
if (nbr < 0)
|
||||||
|
{
|
||||||
|
if (write(1, "-", 1) < 0)
|
||||||
|
return (-10000);
|
||||||
|
count++;
|
||||||
|
p_nbr = (unsigned int)nbr * -1;
|
||||||
|
if (arg->dot < 0)
|
||||||
|
count += print_chars(arg->zero - nbr_size_base(p_nbr, 10) - 1, '0');
|
||||||
|
}
|
||||||
|
else if (arg->dot < 0)
|
||||||
|
count += print_chars(arg->zero - nbr_size_base(p_nbr, 10), '0');
|
||||||
|
count += print_chars(arg->dot - nbr_size_base(p_nbr, 10), '0');
|
||||||
|
count += ft_putnbr_base(p_nbr, "0123456789", 10, arg->dot);
|
||||||
|
return (count);
|
||||||
}
|
}
|
||||||
+12
-6
@@ -6,22 +6,28 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 12:19:16 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 12:19:16 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/21 14:51:15 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 15:46:51 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
int print_pointer(unsigned long long p)
|
int print_pointer(t_arg *arg, unsigned long long p)
|
||||||
{
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
|
count += print_chars(arg->padding - 5, ' ');
|
||||||
if (write(1, "(nil)", 5) < 0)
|
if (write(1, "(nil)", 5) < 0)
|
||||||
return (-1);
|
return (-10000);
|
||||||
return (5);
|
return (5 + count);
|
||||||
}
|
}
|
||||||
|
count += print_chars(arg->padding - nbr_size_base(p, 16) - 2, ' ');
|
||||||
if (write(1, "0x", 2) < 0)
|
if (write(1, "0x", 2) < 0)
|
||||||
return (-1);
|
return (-10000);
|
||||||
return (2 + ft_putnbr_base(p, "0123456789abcdef", 16));
|
return (count + 2 + ft_putnbr_base_ll(p, "0123456789abcdef", 16));
|
||||||
}
|
}
|
||||||
+21
-7
@@ -6,21 +6,35 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 12:02:03 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 12:02:03 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/21 14:54:08 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 15:32:08 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_printf.h"
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
|
|
||||||
int print_str(char *str)
|
int print_str(t_arg *arg, char *str)
|
||||||
{
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
if (!str)
|
if (!str)
|
||||||
{
|
{
|
||||||
|
if (arg->dot < 6 && arg->dot >= 0)
|
||||||
|
return (print_chars(arg->padding, ' '));
|
||||||
|
if (arg->padding > 6)
|
||||||
|
count += print_chars(arg->padding - 6, ' ');
|
||||||
if (write(1, "(null)", 6) < 0)
|
if (write(1, "(null)", 6) < 0)
|
||||||
return (-1);
|
return (-10000);
|
||||||
return (6);
|
return (count + 6);
|
||||||
}
|
}
|
||||||
if (write(1, str, ft_strlen(str)) < 0)
|
if (arg->dot > (int)ft_strlen(str) || arg->dot < 0)
|
||||||
return (-1);
|
arg->dot = ft_strlen(str);
|
||||||
return (ft_strlen(str));
|
if (arg->padding > 0)
|
||||||
|
count += print_chars(arg->padding - arg->dot, ' ');
|
||||||
|
else if (!str[0] && arg->space > 0)
|
||||||
|
return (write(1, " ", 1));
|
||||||
|
if (write(1, str, arg->dot) < 0)
|
||||||
|
return (-10000);
|
||||||
|
return (count + arg->dot);
|
||||||
}
|
}
|
||||||
+38
-5
@@ -6,16 +6,49 @@
|
|||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */
|
/* Created: 2025/11/17 12:26:23 by dgaillet #+# #+# */
|
||||||
/* Updated: 2025/11/17 12:44:47 by dgaillet ### ########lyon.fr */
|
/* Updated: 2025/11/21 14:22:44 by dgaillet ### ########lyon.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_printf.h"
|
#include "ft_printf.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int print_unsigned(unsigned int nbr)
|
static int padding_size(t_arg *arg, unsigned int nbr)
|
||||||
{
|
{
|
||||||
if (nbr == 0)
|
int padding;
|
||||||
return (write(1, "0", 1));
|
int nbr_size;
|
||||||
return (ft_putnbr_base(nbr, "0123456789", 10));
|
|
||||||
|
if (arg->padding < 0)
|
||||||
|
return (0);
|
||||||
|
padding = arg->padding;
|
||||||
|
nbr_size = nbr_size_base(nbr, 10);
|
||||||
|
if (arg->dot > nbr_size || (arg->dot == 0 && !nbr))
|
||||||
|
nbr_size = arg->dot;
|
||||||
|
padding = padding - nbr_size;
|
||||||
|
return (padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int print_nb_flags(t_arg *arg, unsigned int nbr)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int padding;
|
||||||
|
|
||||||
|
padding = padding_size(arg, nbr);
|
||||||
|
count = 0;
|
||||||
|
if (arg->dot >= 0 || arg->zero < 0)
|
||||||
|
count += print_chars(padding, ' ');
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int print_unsigned(t_arg *arg, unsigned int nbr)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
count += print_nb_flags(arg, nbr);
|
||||||
|
if (arg->dot < 0)
|
||||||
|
count += print_chars(arg->zero - nbr_size_base(nbr, 10), '0');
|
||||||
|
count += print_chars(arg->dot - nbr_size_base(nbr, 10), '0');
|
||||||
|
count += ft_putnbr_base(nbr, "0123456789", 10, arg->dot);
|
||||||
|
return (count);
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* utils_flag_bonus.c :+: :+: :+: */
|
/* utils_flag.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
/* By: dgaillet <dgaillet@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
Reference in new issue
Block a user