Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This project has been created as part of the 42 curriculum by syokota.

Description

C99標準規格のlibc内で定義されている、printf関数の cspdiuxX%のフラグに対応した ft_printf関数を自作するプロジェクトです。 ここで作成された静的ライブラリ(libftprintf.a)は、別のC言語のプロジェクトにおいて利用可能です。

Instruction

すべての関数ファイル (*.c) は、cc -Wall -Wextra -Werror のフラグでコンパイルされます。

  • make または make all : 関数をコンパイルし、libftprintf.aを作成します。
  • make clean : コンパイル時に生成されたオブジェクトファイル (*.o) を削除します。
  • make fclean : オブジェクトファイル (*.o) と libftprintf.a を削除します。
  • make re : ライブラリを再コンパイルします。

このライブラリを別のプロジェクトで使用する際には、以下の手順で使用できます。

1. ファイルの配置と準備

新しいプロジェクトのディレクトリ内に、libftprintfのフォルダ (printf.h, libftprintf.a)を配置します。

2. ソースコードのインクルード

.cファイルの先頭で、ヘッダーを読み込みます。

#include "libftprintf/printf.h" // パスは配置場所に合わせて調整

3. コンパイル時のリンク設定

コンパイラにlibftの場所を指定する必要があります。

  • -I : ヘッダファイルがある場所を指定
  • -L : ライブラリファイル (.a) がある場所を指定
  • -l : ライブラリ名を指定 (libft.aの場合、ftprintfと記述)
 cc main.c -I./libftprintf -L./libftprintf -lftprintf

本関数のアルゴリズム

プロトタイプは、以下のとおりです。

int ft_printf(const char *, ...);

標準出力ストリームstdoutに出力を書き込みます。また、stdargの可変長引数機能を介してアクセスされる引数が、出力用にどのように変換されるかを指定するフォーマット文字列の制御下で、出力を書き込みます。フォーマット文字列は、初期シフト状態(存在する場合)で始まり、初期シフト状態で終わる文字列です。 フォーマット文字列は、0 個以上のディレクティブで構成されます。 通常の文字(%以外)は、出力ストリームにそのままコピーされます。 本関数に導入されている変換指定子は以下の通りです。

  • %c : int 型の引数をchar 型に変換し,変換結果の文字を書き込む
  • %s : 文字配列の先頭要素へのポインタを文字列に変換する
  • %p : void *型のポインタ引数を16進数形式に変換する
  • %d : int 型の引数を 10 進符号付き整数に変換する
  • %i : int 型の引数を 10 進符号付き整数に変換する
  • %u : unsigned int 型の引数を 10 進符号無し整数に変換する
  • %x : unsigned int 型の引数を 16 進符号無し整数に変換する
  • %X : unsigned int 型の引数を 16 進符号無し整数に変換する
  • %% : %を出力する

正常に終了した場合、本関数は出力されたバイト数(文字列への出力終了に使用されるヌルバイトを除く)を返します。

標準のprintfは、途中で標準出力(ストリーム)が閉じられたりエラーが発生したりした場合、これまで出力した文字数に関わらず即座に負の値を返します。この仕様を忠実に再現するため、本関数では、システムコールであるwrite関数の戻り値を末端の関数ft_printf_char などで必ず受け取り、-1(書き込み失敗)であった場合は即座に処理を中断し、親関数、さらにその親関数へと -1を返し続ける設計にしています。

オーバーフローによる未定義動作の回避のために、整数やメモリアドレスの計算において、以下の型変換(キャスト)を意図的に行う設計にしています。

  • 符号付き整数(%d, %i)の処理では、int型の引数を一度long型に格納してから絶対値の計算を行う。
  • ポインタ(%p)の処理では、void *型のアドレスを一度uintptr_t型 にキャストしてから16進数の計算に渡す。

文字列を複数回走査したり、事前にフォーマット指定子の数を数えたりする無駄な処理を省き、時間計算量 O(N) で最速で出力とカウントを完了させるため、フォーマット文字列(format)を読み進める際、文字列の先頭から末尾\0までを1回の while ループで1文字ずつ解析します。%を検知した場合は次の文字を先読みし、分岐処理を行う設計にしています。

Resources

AIの使用について:

  • va_list型の概念的な理解
  • stdint.hの内容と、uintptr_t型の概念的な理解
  • 複雑なエラーメッセージの解読と原因特定
  • write関数がエラーを出力したときの適切なハンドリング方法について

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages