J’ai créé la fonction ft_putchar(char c) pour afficher un caractère en utilisant la fonction write. Pour utiliser la fonction write, j’ai dû inclure l’en-tête #include <unistd.h>, qui signifie Unix standard. Dans l’appel à write, le premier argument 1 correspond à la sortie standard (stdout). Pour le deuxième argument, j’ai mis &c (et non pas simplement c) car la fonction write attend l’adresse en mémoire de la donnée à écrire. Ici, &c signifie « l’adresse du caractère c ». Enfin, pour afficher un seul caractère, j’ai mis 1 comme troisième argument de write, ce qui signifie 1 octet.
#include<unistd.h>
voidft_print_alphabet(void)
{
for(chara='a'; a<='z'; a++)
{
write(1, &a, 1);
}
}
intmain()
{
ft_print_alphabet();
}
J’ai créé la fonction void ft_print_alphabet(void) pour afficher l’alphabet en minuscules dans l’ordre croissant, à partir de la lettre 'a'. J’ai utilisé une boucle for avec char a = 'a', qui commence à 'a' et s’incrémente jusqu’à 'z', en augmentant de 1 à chaque itération. J’ai utilisé la fonction write pour afficher toutes les lettres de l’alphabet.
#include<unistd.h>
voidft_print_reverse_alphabet(void)
{
for(chara='z'; a>='a'; a--)
{
write(1, &a, 1);
}
}
intmain()
{
ft_print_reverse_alphabet();
}
J’ai créé la fonction void ft_print_reverse_alphabet(void) pour afficher l’alphabet en minuscules dans l’ordre décroissant, à partir de la lettre 'z'. J’ai utilisé une boucle for avec char a = 'z', qui commence à 'z' et décrémente jusqu’à 'a', en diminuant de 1 à chaque itération. J’ai utilisé la fonction write pour afficher toutes les lettres de l’alphabet dans l’ordre inverse.
#include<unistd.h>
voidft_print_numbers(void)
{
for(chara='0'; a<='9'; a++)
{
write(1, &a, 1);
}
}
intmain()
{
ft_print_numbers();
}
J’ai créé la fonction ft_print_numbers pour afficher les chiffres de 0 à 9 sur une seule ligne dans l’ordre croissant. Pour cela, j’ai utilisé une boucle for avec char a, qui commence à '0' et s’incrémente jusqu’à '9'. Ainsi, tous les chiffres apparaissent sur une seule ligne dans l’ordre croissant.
#include<unistd.h>
voidft_is_negative(intn) {
if (n<0)
write(1, "N", 1);
else
write(1, "P", 1);
}
intmain() {
ft_is_negative(3);
}
J’ai utilisé la fonction ft_is_negative, qui affiche N si l’entier passé en paramètre est négatif, et P si l’entier est positif ou égal à 0. Pour cela, j’ai utilisé une structure conditionnelle if pour gérer les deux cas. Dans le premier cas, si le nombre est inférieur à 0, j’affiche N avec la fonction write. Dans le deuxième cas, si le nombre est positif ou égal à 0, j’affiche P également avec write. Ainsi, la fonction affiche correctement N ou P selon la valeur de l’entier.
#include<unistd.h>
voidft_print_comb(void) {
for(chari='0'; i<='7'; i++)
{
for(charj=i+1; j<='8'; j++)
{
for (charm=j+1; m<='9'; m++)
{
write(1, &i,1);
write(1, &j,1);
write(1, &m,1);
if (i!=7&&j!=8&&m!=9)
{
write(1, ", ", 2);
}
}
}
}
}
intmain() {
ft_print_comb();
}
J’ai créé la fonction ft_print_comb, de type void, qui affiche toutes les combinaisons possibles de trois chiffres différents dans l’ordre croissant.
Pour cela, j’ai utilisé trois boucles for imbriquées avec les variables i, j et m :
i représente le premier chiffre et va de '0' à '7'.
j représente le deuxième chiffre et commence à i + 1, jusqu’à '8'.
m représente le troisième chiffre et commence à j + 1, jusqu’à '9'.
Dans chaque itération, j’affiche les chiffres i, j et m avec la fonction write. Pour séparer les combinaisons par une virgule et un espace, j’utilise une condition : si i != '7', j != '8' et m != '9', alors j’écris , avec write(1, ", ", 2) (2 octets). Ainsi, la dernière combinaison (7 8 9) n’est pas suivie d’une virgule ni d’un espace.
#include<unistd.h>
voidft_print_comb2(void) {
for (inti=00; i<=98; i++) {
for (intj=i+1; j<=99; j++) {
charx, y, z, t;
x= (i/10) +'0';
y= (i%10) +'0';
z= (j/10) +'0';
t= (j%10) +'0';
write(1, &x, 1);
write(1, &y, 1);
write(1, " ",1);
write(1, &z, 1);
write(1, &t, 1);
if (!(i==98&&j==99)) {
write(1, ", ", 2);
}
}
}
}
intmain () {
ft_print_comb2();
}
J’ai créé la fonction ft_print_comb2, de type void, qui affiche toutes les combinaisons possibles de deux nombres à deux chiffres différents dans l’ordre croissant.
Pour cela, j’ai utilisé deux boucles for imbriquées :
i va de 0 à 98 et représente le premier nombre.
j va de i + 1 à 99 et représente le deuxième nombre.
Pour chaque combinaison, j’ai séparé les chiffres de chaque nombre :
x = chiffre des dizaines de i → (i / 10) + '0'
y = chiffre des unités de i → (i % 10) + '0'
z = chiffre des dizaines de j → (j / 10) + '0'
t = chiffre des unités de j → (j % 10) + '0'
Remarque importante : on ajoute '0' à chaque chiffre pour le convertir en caractère ASCII (아스키), car la fonction write attend des caractères et non des nombres. Sans + '0', write afficherait le code ASCII correspondant au nombre entier, ce qui ne donnerait pas le chiffre souhaité.
Ensuite, j’affiche les chiffres x, y, un espace, puis z et t avec la fonction write.
Pour séparer les combinaisons par une virgule et un espace, j’utilise la condition : if (!(i == 98 && j == 99)) Ainsi, la dernière combinaison (98 99) n’est pas suivie d’une virgule ni d’un espace. “Si i n’est pas égal à 98 et j n’est pas égal à 99”
! → “ne … pas” (부정)
== → “égal à” (같다)
&& → “et” (그리고)
즉 의미는:
“i가 98이 아니거나, j가 99가 아닌 경우”
여기까지만 하자.....
#include<unistd.h>
voidft_putchar(charc)
{
write(1, &c, 1);
}
voidft_putnbr(intnb)
{
longn;
n=nb;
if (n<0)
{
ft_putchar('-');
n=-n;
}
if (n>9)
{
ft_putnbr(n/10);
n%=10;
}
ft_putchar(n+'0');
}
intmain ()
{
ft_putnbr(-10);
}
Ce programme affiche un nombre entier, même négatif, en utilisant une fonction récursive.
ft_putchar : affiche un caractère sur la sortie standard.
ft_putnbr (fonction récursive) :
Si le nombre est négatif, on affiche '-' et on rend le nombre positif.
Si le nombre a plusieurs chiffres, la fonction s’appelle elle-même pour afficher les chiffres de gauche à droite.
On affiche ensuite le dernier chiffre avec ft_putchar(n + '0').
main : appelle ft_putnbr(-10), ce qui affiche : Remarque : on utilise long pour éviter un dépassement si le nombre est le minimum d’un int.
-exec 앞의 명령어에서 값을 받아온다. (조건을 가지고 찾은 파일들을 대상으로 다음 명령어를 실행하라!) exec를 사용하여 검색한 대상에 추가 명령어를 수행하기 basename 은 파일 이름만 알려준다. 예를 들어서, basename /home/jisoo/ex09/ft_magic 이것을 ft_magic 출력 경로를 알려주지 않고 이름만 뺴준다는 의미 예를 들어 basename /home/jisoo/script.sh 이렇게 나왔다면 다 빼고 이름만 출력 script.sh 근데 find 라는 명령어와 함께쓰면 전체 경로가 나온다. 따라서 basename {} 이렇게 적어줘서 find 가 찾은 경로를 지워주는 것 basename 뒤에 오는 .sh 는 파일 이름에서 .sh 부분은 지워라는 뜻. -exec는 명령어고 이는 ; 이게 나와서 명령이 끝났다는걸 표시해준다. 근데 ; 는
명령어를 연속적으로 실행해주는 것
예 : clear;ls -> clear 실행 후, ls 실행 이를 막기 위해서 \ 넣어준다.
find 파일/ 디렉토리를 재귀적으로 찾아 . 현재 디렉토리에서 시작해라 | (파이프) 앞 명령의 표준 출력(stdout) 을 다음 명령의 표준 입력(stdin)으로 연결하는 연산자 wc = word count (단어/줄/바이트 세기) 명령 -l 옵션은 라인(줄) 수를 센다. 즉, find .가 출력한 줄의 개수 = 항목의 개수 출력 형식: wc -l은 숫자를 오른쪽 정렬해서 출력하므로 앞에 공백들이 붙을 수 있음. 예: " 4\n" 처럼 공백+숫자+개행을 내보냄
총 몇개인지 입력이 되는데 숫자 앞에 공백이 너무 많다. 이 공백을 없애줘야한다. 그렇게 하기 위해서 명령어 sed 사용 sed = stream editor 텍스트 변환 도구 's/.../.../' → substitute(치환) 명령어 형식
앞부분(...)의 패턴을 찾아서
뒷부분(...)으로 바꿔라
s 는 찾아서 바꾸라는 뜻 ^문자열의 맨 시작, 앞 줄 * 스페이스 + * (0회 이상 반복) -> 공백이 0회 이상 반복, 맨 앞에 있는 모든 공백을 의미 / / 이것을 빈 문자열로 바꿔라 -> 줄 맨 앞에 있는 공백 다 지워 find . | wc-l | sed s/^ */ / → "줄 맨 앞의 공백(0개 이상)을 스페이스 하나로 바꿔라"라는 뜻이 돼 (띄어쓰기 안된다) wc 띄어쓰기 -l find . | wc -l | sed 's/^ *//' -> ' ' 사용해야 안전하다. (쉘이 오해하지 않게)
문제풀이 : ifconfig 네트워크 인터페이스(예: en0, lo0 등)의 정보(주소, 상태, MAC, MTU 등)를 출력하는 명령어. 여기서 ether 라는 단어가 MAC 주소(하드웨어 주소) 라인이므로, ether가 포함된 줄을 골라내면 MAC 주소 줄만 얻을 수 있다. | 파이프, 앞 명령의 출력(stdout)을 다음 명령의 입력(stdin)으로 전달한다. 여기서는 ifconfig의 전체 텍스트를 grep으로 넘겨준다. grep -w "ether" grep : 입력에서 특정 패턴(문자열)을 포함한 줄만 골라 출력. -w : 단어 단위 일치 (패턴이 단독 단어로 나왔을 때만 매치). 예: ether만 매치하고 someetherfoo 같은 부분 문자열은 매치하지 않음. 결과: ifconfig에서 ether가 들어간 줄들만 출력된다.
특수문자는 각자 기능이 있기 때문에, 순수히 일반문자로만 사용하려면 \를 이용해야 한다 이해가 잘 안간다. 아무리해도 안됐었다. 드디어 넣었다.
echo -n 42 |tr -d '\n' >\"\\\?\$\*'MaRViN'\*\$\?\\\" 아마 이렇게 적었더랬지.... 우선 echo 42라고 적으면 \n 여기까지 세트다. 근데 문제에서는 "42"만 적으세요. 라고 적혀있어서 \n 부분을 뺐다. -n 이렇게 후에 tr-d '\n' 이것도 띄어쓰기 부분 없애달라고 하는 뜻인데, 따라서 안적어도 되는데 그냥 적었다.
tr = translate or delete characters (문자 치환/삭제). -d : 지정한 문자를 삭제. 예: echo "42!" | tr -d "!" → 결과 = 42 그리고 일반문자로 사용하기 위해 특수문자 앞에 \ 넣기.
깃에 올릴때도 복붙하지 말고 타이핑 해야된단다. git add ex05/"\"\?\$*'MaRViN'*\$?\\\""
dquote 자꾸 나오는데, 탈출 방법은 " + 엔터 애 많이 먹은 문제다 ㅠㅠㅠㅠ 그냥 적고 올려버리자...사실 다 올리고 나면 git에서는 문제 요구 사항에 맞게 잘 나오더라. 아니면 주변 사람들에게 물어보기 !! **
ls -l | awk 'NR % 2 == 1' ls -l 명령은 현재 디렉토리의 **상세 리스트(long format)**를 보여준다. 우리가 원하는 것은 첫 줄(1번째), 세 번째 줄(3번째), 다섯 번째 줄(5번째) | 파이프 ls -l의 출력 결과를 바로 다음 명령어로 넘기기 위해 파이프(|)를 사용 awk는 라인 단위로 처리하는 텍스트 도구 'NR % 2 == 1' 뜻을 풀어보면 NR: awk 내장 변수, 현재 줄 번호(Number of Record) NR % 2: 줄 번호를 2로 나눈 나머지 == 1: 나머지가 1인 줄만 출력
문제풀이 :
cat /etc/passwd 명령어의 출력 결과에서 주석은 삭제하고 두 번째 행부터 시작하여 다른 모든 행들은 출력하되, 각 login들 거꾸로 반전시키고 알파벳 역순으로 정렬한 후, FT_LINE1 과 FT_LINE2 을 포함한 그 사이의 값들만 남겨두세요. 이 때, 각login은 ","로 구분되어야 하며 출력 결과는 "."로 끝나야 합니다.(큰따옴표 없이)
먼저 /etc/passwd 의미는 무엇일까, 이걸 터미널에 cat과 함께 적어보면 시스템 사용자 계정 정보가 들어있다. sed '/#/d' 이거는 우선 #부분 delete 해라 ! #는 주석이다. 따라서 주석 줄 삭제하라는 뜻 cut -d ':' -f1 cut은 구분자로 필드를 잘라내는 명령, -d ':' → :를 구분자로 사용, -f1 → 첫 번째 필드만 선택 첫번째 필드 로그인 이름만 적어라 ?
awk "NR % 2 == 0"
awk는 라인 단위 처리 도구입니다.
NR → 현재 줄 번호(Number of Record)
NR % 2 == 0 → 짝수 줄만 선택 (두 번째 줄부터 한 줄씩)
따라서 **두 번째 줄, 네 번째 줄, …**의 로그인 이름만 남습니다. une ligne sur deux en partant de la seconde" 직역하면 "두 번째 줄부터 시작해서 한 줄에 하나(=한 줄 건너)씩" 이라는 뜻이에요. 즉 출력되는 줄은 2, 4, 6, ... (짝수 줄) 입니다. (반대로 “첫 줄부터 한 줄 건너”면 1,3,5...가 됩니다.)
rev는 문자열을 뒤집음(reverse) 예) daemon → nomaed sort -r sort는 정렬 명령어, -r → 역순(reverse) 정렬, 따라서 로그인 이름이 알파벳 역순으로 정렬됩니다. awk "NR >= $FT_LINE1 && NR <= $FT_LINE2"
NR → 현재 줄 번호
$FT_LINE1과 $FT_LINE2는 환경 변수로 지정된 범위
NR >= $FT_LINE1 && NR <= $FT_LINE2 → 지정된 줄 범위만 남김
예: FT_LINE1=3, FT_LINE2=7 → 3~7번째 줄만 선택
tr '\n' ',' tr은 문자 변환(translator), \n → 줄바꿈, , → 쉼표, 즉 줄바꿈을 쉼표로 바꿈
sed 's/,/, /g' 쉼표 뒤에 공백 추가, s/,/, /g → 모든 쉼표를 , 로 바꿈 sed 's/, $/./' 마지막 쉼표와 공백을 마침표로 바꿈, $는 줄 끝(end of line) 의미 tr -d '\n', 마지막 줄바꿈 제거(-d = delete, 출력이 한 줄로 끝나게 합니다.
FT_NBR1 이 사용하는 문자는 ' \ " ? ! 총 5개 FT_NBR2 이 사용하는 문자도 m r d o c 총 5개 프로그래밍에서 특정 문자들만 사용해서 수를 나타낸다 → 곧 그 문자 집합이 곧 숫자 체계의 자리수(Base) 가 된다. 2개 문자(0,1) → 2진수 10개 문자(0~9) → 10진수 따라서 5진수라고 알 수 있다. 하지만 출력해야 하는 알파벳 집합 "gtaio luSnemf" → 글자가 13개. 따라서 출력은 base 13 으로 변환해야 함. 몇 진수인지 알았으니까 이젠 숫자로 치환해본다. FT_NBR1 기호 집합 ' "\" ? ! \ → 0,1,2,3,4 로 바꿔야 함. FT_NBR2 기호 집합 m r d o c → 0,1,2,3,4 로 바꿔야 함. tr 명령어를 사용하면 간단히 문자 → 숫자 치환 가능 이제 두 수가 base 5임을 알았으니, 실제 계산은 10진수에서 해야 편하다. bc (리눅스 계산기 도구)를 사용하면 ibase=5 로 설정해서 base 5를 해석할 수 있다. 예: echo "ibase=5; 243" | bc → base 5의 243을 10진수로 변환 bc 안에서 ibase=5 로 읽고, 두 숫자를 그냥 + 연산. 예: echo "ibase=5; 243 + 144" | bc → 10진수로 계산 이제 결과를 base 13으로 표현해야 함 bc는 obase=13 옵션으로 바꾸면 됨 echo "obase=13; ibase=5; <숫자들>" | bc base 13의 기본 기호는 0123456789ABC 문제에서는 gtaio luSnemf 라는 13글자를 쓰라고 했으니, 다시 문자 변환 필요. 여기서 tr 로 0123456789ABC → gtaio luSnemf 치환.
입력값에서 문자 → 숫자 치환 (base 5 표현 확보).
bc 로 base 5 → base 10 변환.
두 값 더하기.
결과를 base 13으로 변환.
base 13 기호 → 문제에서 요구한 알파벳 집합으로 변환.
echo $FT_NBR1 + $FT_NBR2
예: FT_NBR1과 FT_NBR2는 문제에서 정의한 특수문자(alphabet)로 구성된 문자열입니다.
echo는 두 변수를 "값1 + 값2" 형태로 한 줄로 출력합니다. (플러스 기호로 두 수를 더하는 식을 만들기 위함)
출력 예(가정): \'?" + rcrdmddd
중요: 출력 중에 공백/더하기 기호가 있어야 bc에 "숫자1 + 숫자2" 형식으로 전달됩니다. 연속된 tr들 — 특수문자들을 숫자(0..4) 로 바꾼다
파이프라인에 연달아 있는 tr들은 각 문자 → 0..4 로 바꿔서 결국 기수 5의 숫자열을 만들기 위해 사용됩니다.
각 tr의 의미:
tr "\'" "0" 작은따옴표 문자(') → 0
tr "\\" "1" 백슬래시(\) → 1 (백슬래시는 셸에서 이스케이프 문자라서 "\\"처럼 두 번 써서 표현합니다)
tr "\"" "2" 큰따옴표(") → 2
tr "\?" "3" 물음표(?) → 3
tr "\!" "4" 느낌표(!) → 4
이 다섯 tr은 FT_NBR1 쪽에 쓰이는 문자들(문제에서 정의한 첫 알파벳)을 0..4로 바꿔줍니다.
과적으로 echo의 출력 문자열은 "숫자열 + 숫자열" 형태(단, 숫자들은 0..4만 사용)로 바뀝니다. 예: 1032+14120222 같은 문자열이 됩니다. 이 숫자열은 5진수 표기임을 다음 단계에서 알려줍니다.
주의(쉘/인용): tr에서 "\\"나 \" 같은 것은 쉘에서 적절히 이스케이프해야 하니 실전 입력시 따옴표/백슬래시에 신경 써야 합니다.
xargs echo "obase=13;ibase=5;"
tr까지 거쳐 나온 문자열(예: 1032 + 14120222)을 xargs가 인수로 받아서 echo "obase=13;ibase=5;" ARGUMENTS... 형태로 조합합니다.
이 줄을 bc로 넘기면 bc가 차례로 obase=13;(출력 진법 13 설정), ibase=5;(입력 진법 5 설정), 그리고 1032+14120222(5진수끼리 더하라)를 처리하게 됩니다.
왜 obase를 먼저 설정하나? bc는 숫자 리터럴(예: 13)을 현재 ibase로 해석하므로 순서에 따라 해석이 달라질 수 있습니다. 일반적으로 안전하게 obase(출력 진법) 먼저 설정한 뒤 ibase(입력 진법)를 바꿔서 그 다음 입력 숫자들이 올바르게 5진수로 해석되도록 합니다.
| bc
이제 bc(임의 정밀도 계산기)가 다음을 수행:
obase=13 → 출력 진법을 13진수로 설정
ibase=5 → 이후 등장하는 숫자 리터럴을 5진수로 해석
1032+14120222 → 두 5진수 숫자를 더한 값을 계산
bc는 결과를 설정된 obase(13) 로 출력합니다. 13진수에서 자릿값은 0..9, A, B, C 로 표현됩니다.
예:
만약 bc가 결과로 10A 를 출력했다면 (13진수) 그 문자열이 다음 단계로 전달됩니다.
맨 마지막 tr "0123456789ABC" "gtaio luSnemf"
bc가 출력한 13진수 숫자문자들 (0 1 2 3 4 5 6 7 8 9 A B C)을 문자 알파벳으로 치환합니다.