General
Allowed editors: vi, vim, emacs
All your files will be compiled on Ubuntu 20.04 LTS using gcc, using the options -Wall -Werror -Wextra -pedantic -std=gnu89
All your files should end with a new line
A README.md file, at the root of the folder of the project is mandatory
Your code should use the Betty style. It will be checked using betty-style.pl and betty-doc.pl
You are not allowed to use global variables
No more than 5 functions per file
In the following examples, the main.c files are shown as examples. You can use them to test your functions, but you don’t have to push them to your repo (if you do we won’t take them into account). We will use our own main.c files at compilation. Our main.c files might be different from the one shown in the examples
The prototypes of all your functions should be included in your header file called main.h
Don’t forget to push your header file
All your header files should be include guarded
Note that we will not provide the \_putchar function for this project
GitHub
There should be one project repository per group. The other members do not fork or clone the project to ensure only one of the team has the repository in their github account otherwise you risk scoring 0%
More Info
Authorized functions and macros
write (man 2 write)
malloc (man 3 malloc)
free (man 3 free)
va\_start (man 3 va\_start)
va\_end (man 3 va\_end)
va\_copy (man 3 va\_copy)
va\_arg (man 3 va\_arg)
Compilation
Your code will be compiled this way:
$ gcc -Wall -Werror -Wextra -pedantic -std=gnu89 \*.c
As a consequence, be careful not to push any c file containing a main function in the root directory of your project (you could have a test folder containing all your tests files including main functions)
Our main files will include your main header file (main.h): #include main.h
You might want to look at the gcc flag -Wno-format when testing with your \_printf and the standard printf
Write a function that produces output according to a format.
Prototype: int \_printf(const char \*format, ...);
Returns: the number of characters printed (excluding the null byte used to end output to strings)
write output to stdout, the standard output stream
format is a character string. The format string is composed of zero or more directives. See man 3 printf for more detail. You need to handle the following conversion specifiers:
c
s
%
You don’t have to reproduce the buffer handling of the C library printf function
You don’t have to handle the flag characters
You don’t have to handle field width
You don’t have to handle precision
You don’t have to handle the length modifiers
Handle the following conversion specifiers:
d
i
You don’t have to handle the flag characters
You don’t have to handle field width
You don’t have to handle precision
You don’t have to handle the length modifiers
Handle the following custom conversion specifiers:
b: the unsigned int argument is converted to binary
alex@ubuntu:~/c/printf$ cat main.c
#include "main.h"
/\*\*
 \* main - Entry point
 \*
 \* Return: Always 0
 \*/
int main(void)
{
 \_printf("%b\n", 98);
 return (0);
}
alex@ubuntu:~/c/printf$ gcc -Wall -Wextra -Werror -pedantic -std=gnu89 main.c
alex@ubuntu:~/c/printf$ ./a.out
1100010
alex@ubuntu:~/c/printf$
Handle the following conversion specifiers:
u
o
x
X
You don’t have to handle the flag characters
You don’t have to handle field width
You don’t have to handle precision
You don’t have to handle the length modifiers
Use a local buffer of 1024 chars in order to call write as little as possible.
Handle the following custom conversion specifier:
S : prints the string.
Non printable characters (0 < ASCII value < 32 or >= 127) are printed this way: \x, followed by the ASCII code value in hexadecimal (upper case - always 2 characters)
alex@ubuntu:~/c/printf$ cat main.c
#include "main.h"
/\*\*
 \* main - Entry point
 \*
 \* Return: Always 0
 \*/
int main(void)
{
 \_printf("%S\n", "Best\nSchool");
 return (0);
}
alex@ubuntu:~/c/printf$ gcc -Wall -Wextra -Werror -pedantic -std=gnu89 main.c
alex@ubuntu:~/c/printf$ ./a.out
Best\x0ASchool
alex@ubuntu:~/c/printf$
Handle the following conversion specifier: p.
You don’t have to handle the flag characters
You don’t have to handle field width
You don’t have to handle precision
You don’t have to handle the length modifiers
Handle the following flag characters for non-custom conversion specifiers:
+
space
#
Handle the following length modifiers for non-custom conversion specifiers:
l
h
Conversion specifiers to handle: d, i, u, o, x, X

Handle the precision for non-custom conversion specifiers.
Handle the 0 flag character for non-custom conversion specifiers.
Handle the - flag character for non-custom conversion specifiers.
Handle the following custom conversion specifier:
r : prints the reversed string
Handle the following custom conversion specifier:
R: prints the rot13'ed string

#ifndef MAIN\_H
#define MAIN\_H

#include 

/\*\*
 \* struct print\_function - struct for format specifier and corresponding function
 \* @specifier: format specifier
 \* @f: pointer to corresponding function
 \*/
typedef struct print\_function
{
 char specifier;
 int (\*f)(va\_list);
} print\_f;

int \_printf(const char \*format, ...);
int print\_char(va\_list args);
int print\_string(va\_list args);
int print\_int(va\_list args);
int print\_unsigned\_int(va\_list args);
int print\_binary(va\_list args);
int print\_hex(va\_list args);
int print\_octal(va\_list args);
int print\_pointer(va\_list args);
int print\_reverse(va\_list args);
int print\_rot13(va\_list args);

#endif /\* MAIN\_H \*/
eneral
허용 편집기: vi, vim, emacs
모든 파일은 gcc를 사용하여 Ubuntu 20.04 LTS에서 -Wall -Werror -Wextra -pedantic -std=gnu89 옵션을 사용하여 컴파일됩니다.
모든 파일은 새 줄로 끝나야 합니다.
프로젝트 폴더의 루트에는 README.md 파일이 필수입니다.
코드는 Betty 스타일을 사용해야 합니다. betty-style.pl 및 betty-doc.pl을 사용하여 확인합니다.
전역 변수는 사용할 수 없습니다.
파일당 함수 5개 이하
다음 예제에서는 main.c 파일을 예시로 보여줍니다. 이 파일을 사용하여 함수를 테스트할 수 있지만 리포지토리에 푸시할 필요는 없습니다(푸시하는 경우 고려하지 않음). 컴파일 시에는 자체 main.c 파일을 사용합니다. 우리의 main.c 파일은 예제에 표시된 것과 다를 수 있습니다.
모든 함수의 프로토타입은 main.h라는 헤더 파일에 포함되어야 합니다.
헤더 파일을 푸시하는 것을 잊지 마세요.
모든 헤더 파일은 가드된 상태로 포함해야 합니다.
이 프로젝트에는 \_putchar 함수를 제공하지 않습니다.
GitHub
그룹당 하나의 프로젝트 리포지토리가 있어야 합니다. 다른 팀원이 프로젝트를 포크하거나 복제하여 팀원 중 한 명만 GitHub 계정에 리포지토리를 보유하도록 하지 않으면 점수가 0%가 될 위험이 있습니다.
자세한 정보
승인된 함수 및 매크로
write (남자 2 쓰기)
malloc (남자 3 malloc)
free (남자 3 free)
VA\_START (MAN 3 VA\_START)
VA\_END (남자 3 VA\_END)
VA\_COPY (MAN 3 VA\_COPY)
VA\_ARG (MAN 3 VA\_ARG)
컴파일
코드는 다음과 같이 컴파일됩니다:
$ gcc -Wall -Werror -Wextra -pedantic -std=gnu89 \*.c
결과적으로 프로젝트의 루트 디렉터리에 메인 함수가 포함된 c 파일을 푸시하지 않도록 주의하세요(메인 함수를 포함한 모든 테스트 파일이 포함된 테스트 폴더를 가질 수 있습니다).
메인 파일에는 메인 헤더 파일(main.h)이 포함됩니다: #include main.h
gcc 플래그 -Wno-format을 사용하여 테스트할 때 \_printf와 표준 printf를 사용하는 것이 좋습니다.
형식에 따라 출력을 생성하는 함수를 작성합니다.
프로토타입: int \_printf(const char \*format, ...);
반환: 인쇄된 문자 수(문자열로 출력을 끝내는 데 사용되는 널 바이트 제외)
표준 출력 스트림인 stdout에 출력을 씁니다.
형식은 문자열입니다. 형식 문자열은 0개 이상의 지시어로 구성됩니다. 자세한 내용은 man 3 printf를 참조하세요. 다음 변환 지정자를 처리해야 합니다:
c
s
%
C 라이브러리 printf 함수의 버퍼 처리를 재현할 필요가 없습니다.
플래그 문자를 처리할 필요가 없습니다.
필드 너비를 처리할 필요가 없습니다.
정밀도를 처리할 필요가 없습니다.
길이 수정자를 처리할 필요가 없습니다.
다음 변환 지정자를 처리합니다:
d
i
플래그 문자를 처리할 필요가 없습니다.
필드 너비를 처리할 필요가 없습니다.
정밀도를 처리할 필요가 없습니다.
길이 수정자를 처리할 필요가 없습니다.
다음 사용자 지정 변환 지정자를 처리합니다:
b: 부호 없는 인수가 바이너리로 변환됩니다.
alex@ubuntu:~/c/printf$ cat main.c
#include "main.h"
/\*\*
 \* main - 진입점
 \*
 \* Return: 항상 0
 \*/
int main(void)
{
 \_printf("%b\n", 98);
 return (0);
}
alex@ubuntu:~/c/printf$ gcc -Wall -Wextra -Werror -pedantic -std=gnu89 main.c
alex@ubuntu:~/c/printf$ ./a.out
1100010
alex@ubuntu:~/c/printf$
다음 변환 지정자를 처리합니다:
u
o
x
X
플래그 문자를 처리할 필요가 없습니다.
필드 너비를 처리할 필요가 없습니다.
정밀도를 처리할 필요가 없습니다.
길이 수정자를 처리할 필요가 없습니다.
쓰기를 가능한 한 적게 호출하려면 1024자의 로컬 버퍼를 사용합니다.
다음 사용자 지정 변환 지정자를 처리합니다:
S: 문자열을 인쇄합니다.
인쇄할 수 없는 문자(0 < ASCII 값 < 32 또는 >= 127)는 이 방식으로 인쇄됩니다: \x, 그 뒤에 16진수(대문자 - 항상 2자)로 된 ASCII 코드 값
alex@ubuntu:~/c/printf$ cat main.c
#include "main.h"
/\*\*
 \* main - 진입점
 \*
 \* Return: 항상 0
 \*/
int main(void)
{
 \_printf("%S\n", "Best\nSchool");
 return (0);
}
alex@ubuntu:~/c/printf$ gcc -Wall -Wextra -Werror -pedantic -std=gnu89 main.c
alex@ubuntu:~/c/printf$ ./a.out
Best\x0ASchool
alex@ubuntu:~/c/printf$
다음 변환 지정자를 처리합니다: p.
플래그 문자를 처리할 필요가 없습니다.
필드 너비를 처리할 필요가 없습니다.
정밀도를 처리할 필요가 없습니다.
길이 수정자를 처리할 필요가 없습니다.
사용자 정의 변환 지정자가 아닌 경우 다음 플래그 문자를 처리합니다:
+
공백
#
사용자 정의 변환 지정자가 아닌 경우 다음 길이 수정자를 처리합니다:
l
h
처리할 변환 지정자: d, i, u, o, x, X

사용자 정의가 아닌 변환 지정자에 대한 정밀도를 처리합니다.
사용자 정의 변환 지정자가 아닌 경우 0 플래그 문자를 처리합니다.
사용자 정의 변환 지정자가 아닌 경우 - 플래그 문자를 처리합니다.
다음 사용자 지정 변환 지정자를 처리합니다:
r : 반전된 문자열을 인쇄합니다.
다음 사용자 정의 변환 지정자를 처리합니다:
R: 회전된 문자열을 출력합니다.

#ifndef MAIN\_H
#정의 MAIN\_H

#포함 

/\*\*
 \* 구조체 print\_function - 포맷 지정자 및 해당 f를 위한 구조체