]> git.dkaiser.de - 42/libft.git/commitdiff
Add ft_printf
authorDominik Kaiser <dkaiser@2-F-4.42heilbronn.de>
Fri, 12 Apr 2024 14:44:17 +0000 (16:44 +0200)
committerDominik Kaiser <dkaiser@2-F-4.42heilbronn.de>
Fri, 12 Apr 2024 14:44:17 +0000 (16:44 +0200)
Makefile
ft_printaddr.c [new file with mode: 0644]
ft_printf.c [new file with mode: 0644]
ft_printf.h [new file with mode: 0644]
ft_printhex.c [new file with mode: 0644]
ft_printnbr.c [new file with mode: 0644]
libft.h

index 1fdbab6739bf5cca73776b744c7b9e8ae8c2a00c..9e94fb2c033b12398bca0fd54ddaf3baffdfd13e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,10 @@ SRC_FILES = ft_atoi.c \
                        ft_substr.c \
                        ft_tolower.c \
                        ft_toupper.c \
+                       ft_printf.c \
+                       ft_printnbr.c \
+                       ft_printhex.c \
+                       ft_printaddr.c
 
 
 OBJ_FILES = $(SRC_FILES:.c=.o)
diff --git a/ft_printaddr.c b/ft_printaddr.c
new file mode 100644 (file)
index 0000000..f60ce0d
--- /dev/null
@@ -0,0 +1,42 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_printaddr.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/15 10:33:53 by dkaiser           #+#    #+#             */
+/*   Updated: 2024/03/18 11:42:58 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_printf.h"
+
+static void    printaddr_rec(unsigned long addr, int *len)
+{
+       char    c;
+       int             success;
+
+       if (*len < 0)
+               return ;
+       if (addr % 16 < 10)
+               c = '0' + (addr % 16);
+       else
+               c = ('a' - 10) + (addr % 16);
+       if (addr > 15)
+               printaddr_rec(addr / 16, len);
+       success = write(1, &c, 1);
+       if (success < 0 || *len < 2)
+               *len = -1;
+       else
+               (*len)++;
+}
+
+int    ft_printaddr(void *addr)
+{
+       int     len;
+
+       len = write(1, "0x", 2);
+       printaddr_rec((unsigned long)addr, &len);
+       return (len);
+}
diff --git a/ft_printf.c b/ft_printf.c
new file mode 100644 (file)
index 0000000..fc77f81
--- /dev/null
@@ -0,0 +1,90 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_printf.c                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/12 18:18:59 by dkaiser           #+#    #+#             */
+/*   Updated: 2024/03/18 11:42:34 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_printf.h"
+
+static int     print_char(char c)
+{
+       return (write(1, &c, 1));
+}
+
+static int     print_str(char *str)
+{
+       int     success;
+       int     len;
+
+       if (str)
+       {
+               len = 0;
+               while (str[len])
+                       len++;
+               success = write(1, str, len);
+               if (success < 0)
+                       return (-1);
+               return (len);
+       }
+       else
+       {
+               success = write(1, "(null)", 6);
+               if (success == 6)
+                       return (6);
+               return (-1);
+       }
+}
+
+static int     print_conv(va_list args, char c)
+{
+       if (c == 'c')
+               return (print_char(va_arg(args, int)));
+       if (c == 's')
+               return (print_str(va_arg(args, char *)));
+       if (c == 'p')
+               return (ft_printaddr(va_arg(args, void *)));
+       if (c == 'd' || c == 'i')
+               return (ft_printnbr(va_arg(args, int)));
+       if (c == 'u')
+               return (ft_printunbr(va_arg(args, unsigned int)));
+       if (c == 'x' || c == 'X')
+               return (ft_printhex(va_arg(args, unsigned int), c));
+       if (c == '%')
+               return (print_char('%'));
+       return (-1);
+}
+
+int    ft_printf(const char *fmt, ...)
+{
+       int             result;
+       int             last_result;
+       int             success;
+       va_list args;
+
+       result = 0;
+       va_start(args, fmt);
+       while (*fmt)
+       {
+               last_result = result;
+               if (*fmt == '%')
+                       result += print_conv(args, *(++fmt));
+               else
+               {
+                       success = write(1, fmt, 1);
+                       if (success <= 0)
+                               return (-1);
+                       result++;
+               }
+               fmt++;
+               if (result < last_result)
+                       return (-1);
+       }
+       va_end(args);
+       return (result);
+}
diff --git a/ft_printf.h b/ft_printf.h
new file mode 100644 (file)
index 0000000..22f6a2a
--- /dev/null
@@ -0,0 +1,24 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_printf.h                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/12 18:19:47 by dkaiser           #+#    #+#             */
+/*   Updated: 2024/03/15 13:33:09 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef FT_PRINTF_H
+# define FT_PRINTF_H
+
+# include <stdarg.h>
+# include <unistd.h>
+
+int    ft_printf(const char *fmt, ...);
+int    ft_printnbr(int nbr);
+int    ft_printunbr(unsigned int nbr);
+int    ft_printhex(unsigned int nbr, char fmt);
+int    ft_printaddr(void *addr);
+#endif // FT_PRINTF_H
diff --git a/ft_printhex.c b/ft_printhex.c
new file mode 100644 (file)
index 0000000..4605eac
--- /dev/null
@@ -0,0 +1,44 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_printhex.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/13 15:50:35 by dkaiser           #+#    #+#             */
+/*   Updated: 2024/03/18 11:42:46 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_printf.h"
+
+static void    printhex_rec(unsigned int nbr, char fmt, int *len)
+{
+       char    c;
+       int             success;
+
+       if (*len < 0)
+               return ;
+       if (nbr % 16 < 10)
+               c = '0' + (nbr % 16);
+       else
+               c = (fmt - 33) + (nbr % 16);
+       if (nbr > 15)
+               printhex_rec(nbr / 16, fmt, len);
+       if (*len < 0)
+               return ;
+       success = write(1, &c, 1);
+       if (success < 0)
+               *len = -1;
+       else
+               (*len)++;
+}
+
+int    ft_printhex(unsigned int nbr, char fmt)
+{
+       int     len;
+
+       len = 0;
+       printhex_rec(nbr, fmt, &len);
+       return (len);
+}
diff --git a/ft_printnbr.c b/ft_printnbr.c
new file mode 100644 (file)
index 0000000..2a42ed8
--- /dev/null
@@ -0,0 +1,80 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_printnbr.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/03/13 15:18:40 by dkaiser           #+#    #+#             */
+/*   Updated: 2024/03/18 11:41:27 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "ft_printf.h"
+
+static void    printnbr_rec(int n, int *len)
+{
+       char    c;
+       int             success;
+
+       if (*len < 0)
+               return ;
+       c = '0' + n % 10;
+       if (n > 9)
+               printnbr_rec(n / 10, len);
+       if (*len < 0)
+               return ;
+       success = write(1, &c, 1);
+       if (success < 0)
+               *len = -1;
+       else
+               (*len)++;
+}
+
+int    ft_printnbr(int nbr)
+{
+       int     len;
+
+       len = 0;
+       if (nbr == -2147483648)
+               return (write(1, "-2147483648", 11));
+       if (nbr < 0)
+       {
+               len = write(1, "-", 1);
+               nbr *= -1;
+       }
+       printnbr_rec(nbr, &len);
+       if (len < 0)
+               return (-1);
+       return (len);
+}
+
+static void    printunbr_rec(unsigned int n, int *len)
+{
+       char    c;
+       int             success;
+
+       if (*len < 0)
+               return ;
+       c = '0' + n % 10;
+       if (n > 9)
+               printunbr_rec(n / 10, len);
+       if (*len < 0)
+               return ;
+       success = write(1, &c, 1);
+       if (success < 0)
+               *len = -1;
+       else
+               (*len)++;
+}
+
+int    ft_printunbr(unsigned int nbr)
+{
+       int     len;
+
+       len = 0;
+       printunbr_rec(nbr, &len);
+       if (len < 0)
+               return (-1);
+       return (len);
+}
diff --git a/libft.h b/libft.h
index 148094fabfa4baa475f4d9931306748e1558c444..0e35f359d1541fdf054c5957231db90983f0b0b3 100644 (file)
--- a/libft.h
+++ b/libft.h
@@ -6,13 +6,14 @@
 /*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/10 16:37:54 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/03/11 13:11:23 by dkaiser          ###   ########.fr       */
+/*   Updated: 2024/04/12 16:44:02 by dkaiser          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef LIBFT_H
 # define LIBFT_H
 
+# include "ft_printf.h"
 # include <stdlib.h>
 # include <string.h>
 # include <unistd.h>