영상 스타일 적용 06 | Swiss Motion Graphics로 C 문자열의 여섯 칸을 격자 영상으로 바꾸기

Hello 다섯 글자와 여섯 칸 배열을 스위스 격자로 보여 주는 영상 썸네일

AI AUTOMATA · 영상 스타일 적용 06 · SWISS MOTION GRAPHICS

Hello는 다섯 글자인데 왜 여섯 칸일까 — 격자로 보는 C 문자열

이 글을 읽고 나면 char str[] = "Hello";가 왜 6칸을 쓰는지, sizeof와 strlen이 왜 6과 5로 다른지, 그리고 printf의 %s가 어디서 멈추는지를 한 장의 격자 그림으로 설명할 수 있습니다. 그 설명을 스위스 타이포그래피 스타일의 89초 영상으로 만들고, 사용한 지침과 프롬프트, 실행 검증을 함께 공개합니다.

먼저 밝혀 둡니다. ‘사례06’은 AI 오토마타 연재 번호이며 원본 사이트의 공식 순번이 아닙니다. 이번 영상은 설치형 스킬을 호출한 결과가 아니라, 원본 저장소의 STYLE.md 스타일 지침을 읽어 적용하고 원본의 시간 함수 파일(ease.js, MIT)만 가져와 새로 만든 것입니다. 영상 속 실행 코드는 검증용 자체 코드이며 교재 원문이 아닙니다.

1. 무엇이 달라졌나

교재는 그림 8.6 한 장으로 ‘문자 다섯 개 + 널 문자 하나’를 보여 줍니다. 영상은 이 그림을 그대로 옮기지 않고 격자 자체가 뜻을 갖도록 다시 짰습니다. 화면 오른쪽 절반을 정확히 여섯 모듈로 나누고, 한 모듈을 char 한 칸(1바이트)으로 정했습니다. 그러면 “다섯 글자인데 여섯 칸”이라는 질문이 화면의 구조 그 자체가 됩니다.

또 하나의 변화는 색입니다. 영상 전체에서 빨강은 널 종료 문자 칸에만 씁니다. 다른 모든 요소가 박자에 맞춰 정확히 착지하는 동안, 널 칸만 선형으로 천천히 칠해집니다. 원본 스타일이 말하는 ‘규칙 속의 단 하나의 예외’를 눈에 보이지 않는 문자 \0에 맡긴 것입니다.

2. 원본 스타일 예시: Swiss Motion Graphics

원본은 Lemomo(LemoLab)의 영상 스타일 모음 Lemo-Opuscar에 있는 Swiss Motion Graphics(식별자 swiss-motion)입니다. 시연 작품 Five Rules for a Poster(0:44)는 다섯 가지 스위스 디자인 규칙으로 콘서트 포스터 한 장이 스스로 짜이고, 마지막 다섯째 규칙에서 빨간 원 하나만 격자를 벗어나는 이야기입니다. 아래 영상은 원작자의 작품이며 원본 주소를 그대로 연결했습니다.

원작: Lemomo / LemoLab, Five Rules for a Poster — Swiss Motion Graphics 시연 영상(CC BY 4.0). 재생되지 않으면 아래 ‘원본 영상 열기’를 이용하세요.

STYLE.md의 핵심은 네 가지입니다. 모든 요소는 격자에 붙고 모든 움직임은 박자에 떨어지며 튀지 않는다. 종이·검정·회색에 신호색은 하나뿐이다. 거대한 숫자 옆에 아주 작은 기술 메모를 두는 극단적인 크기 대비. 그리고 등장은 닦기와 클립 공개, 삭제는 칼로 자르기이며 페이드는 쓰지 않는다.

3. 교재 근거: 기초 C언어 8장 245~247쪽

쪽내용
245쪽Section 03 문자열과 char 배열 · 01 C언어와 문자열. 1 문자열 = 문자 배열, [그림 8.6] 문자 배열의 예시(인덱스 0~5, 'H' 'e' 'l' 'l' 'o' \0, 값 72 101 108 108 111 0), 2 널 문자: printf 같은 함수는 널 문자를 만날 때까지 읽는다
246쪽3 문자열을 위한 char 배열 선언과 초기화: char str[] = "Hello"; — "Hello"(5글자)와 널 문자(1글자)를 합쳐 총 6개의 char 공간
247쪽4 크기 지정 시 주의점: "Hello"(5글자)를 저장하려면 최소 char str[6];

PDF 쪽번호와 인쇄 쪽번호가 같음을 페이지 이미지로 확인했습니다. 교재 그림은 그대로 싣지 않고 아래처럼 다시 그렸습니다.

0H721e1012l1083l1084o1115\00인덱스str값문자 5개 (strlen = 5)널 종료 문자

자체 도식 1 · 6칸 배열. 그림 8.6의 내용을 격자 규칙으로 다시 그린 것입니다.

4. 실제 적용 방법

설치형 스킬(lemo-opuscar 플러그인)은 설치하지도 호출하지도 않았습니다. 대신 STYLE.md 전문을 읽고 규칙을 하나씩 이번 교재 내용에 대응시켰습니다. 원본에서 가져온 코드는 박자와 이징을 계산하는 ease.js(MIT) 한 파일뿐이고, 레이아웃·장면·소리는 모두 새로 만들었습니다.

원본 규칙이번 적용바꾼 점과 이유
12단 프레임 격자, 펼친 면왼쪽 페이지 = 진술과 큰 숫자, 오른쪽 페이지 = 배열없음
격자가 뜻을 갖는다오른쪽 페이지 6모듈 = char 6칸(1모듈 = 1바이트)없음
신호색 하나, 주인공에게만빨강은 널 종료 문자 칸에만없음
예외는 선형으로 움직인다널 칸만 선형으로 칠해지고, 짧은 사인음으로 ‘노래’한다없음
극단적 크기 대비큰 숫자 5·6, 6·5, ?·?, 3·2 옆에 20 px 메모두 숫자가 ‘56’처럼 붙어 읽혀 세로 괘선을 추가
등장 = 클립 공개, 삭제 = 칼칸은 위에서 닦이듯, 숫자는 네 단계로, 장면 끝은 칼로 잘림없음
한 글꼴 가족본문 Pretendard 한 가족 + 코드만 JetBrains Mono원본 예시 글꼴에는 한글이 없고, '\0'·'0'·'l'·'1'을 구별하려면 등폭 글꼴이 필요
자막도 레이아웃의 일부왼쪽 1단의 회색 머리말 + 굵은 진술, 단어별 공개, 4~8초 유지음성이 없어 진술을 읽을 시간만큼 움직임을 멈춤
박자 격자를 가진 음악, 인쇄 효과음, 음성120 BPM 음악과 효과음을 새로 합성, 장마다 악기 하나씩음성 없음(자막형). 예측 질문에서는 드럼을 빼고 틱만 남김
원작 엔드카드 사용 금지마지막 한 줄 “문자열의 끝, \0”과 작은 출처 표기LemoLab 서명 없음

5. 입력 파일과 제작 단계

  1. 교재 대조. PDF 243~249쪽을 페이지 이미지로 열어 그림 8.6, 246쪽 코드 상자, 247쪽 크기 규칙을 확인했습니다.
  2. 원본 확인. 저장소 커밋을 기록하고 STYLE.md·DEMO.md·CREDITS를 읽었습니다. 원본 영상은 2초 간격 프레임으로 확인했고 소리는 듣지 않았습니다.
  3. 검증 코드 실행. 영상에 쓸 값을 먼저 gcc로 실행해 확정했습니다(아래 8절).
  4. 격자 설계. 프레임 12단, 배열 6모듈, 빨강의 자리, 120 BPM의 박자를 먼저 정했습니다.
  5. 장면 코드 작성과 정지 화면 점검. 브라우저 캔버스로 한 프레임씩 그리고, 주요 시점을 정지 화면으로 뽑아 고쳤습니다.
  6. 렌더링과 전체 확인. 89초(2,136프레임)를 MP4로 묶고, 처음부터 끝까지 1초 간격 프레임으로 확인한 뒤 고쳐 다시 렌더링했습니다.

6. 프롬프트 전문

네 프롬프트 모두 AI 오토마타 자체 응용문입니다. 원작자의 공개 프롬프트는 원본 STYLE.md입니다. ‘최초·점검·실제 수정’은 이번 작업에서 실제로 수행한 내용이고, ‘확장’은 아직 실행하지 않았습니다.

최초 프롬프트 (실제 사용 · 정리본)
lemo-opuscar 저장소의 styles/swiss-motion/STYLE.md(Swiss Motion Graphics)를 끝까지 읽고 그 규칙으로 60~90초 영상을 만들어라.
시간 함수는 같은 폴더 demo/ease.js(MIT)의 cubic-bezier(.7,0,.2,1)·snap·steps를 쓴다. 원작 데모(Five Rules for a Poster)의 이야기·포스터·악보·음악·엔드카드는 쓰지 않는다.
시작할 때 모델, 실행 환경, 읽은 파일과 커밋을 밝혀라. 파일에 접근하지 못하면 추정으로 대체하지 말라.

[교재 입력 — 기초 C언어 8장 Section 03, 245~247쪽. 페이지 이미지로 대조]
- 245쪽: C언어에는 문자열 전용 자료형이 없고 char 배열로 다룬다. 그림 8.6: 인덱스 0~5, 'H' 'e' 'l' 'l' 'o' '\0', 값 72 101 108 108 111 0.
  모든 문자열 끝에는 널(Null) 종료 문자 \0. printf 같은 함수는 널 문자를 만날 때까지 읽는다.
- 246쪽: char str[] = "Hello"; → "Hello"(5글자) + 널 문자(1글자) = 6개의 char 공간.
- 247쪽: "Hello"(5글자)를 저장하려면 최소 char str[6].

[검증용 자체 코드 — 교재 원문이라고 쓰지 말 것]
#include <stdio.h>
#include <string.h>
int main(void) {
    char str[] = "Hello";
    printf("sizeof=%zu, strlen=%zu\n", sizeof str, strlen(str));
    return 0;
}
gcc로 실행해 sizeof=6, strlen=5를 확인하고, char s[] = "AI";(3, 2)도 실행한다.
배열 이름에 쓴 sizeof와 함수 매개변수(포인터)의 sizeof가 다르다는 점은 메모로만 밝히고 일반화하지 않는다.
널 없는 배열을 %s로 읽는 코드는 실행하지 않고 '정의되지 않은 동작'으로만 설명한다. 영문 ASCII 예제로 한정한다.

[디자인 체계]
- 프레임: 1920×1080, 12단(여백 96, 단 122, 간격 24). 펼친 면: 왼쪽 페이지 1~6단 = 진술과 큰 숫자, 오른쪽 7~12단 = 배열.
- 배열 격자: 오른쪽 페이지를 6모듈 × 142 px로 나눈다. 격자 한 칸 = char 1개(1바이트). 칸은 평평한 흰 사각형, 문자는 등폭.
- 색: 종이색 #EAE9E5, 흰색, 검정 #111111, 회색, 신호색 빨강 #E30613 하나. 빨강은 널 종료 문자 칸에만 쓴다(마지막 장면의 '\0' 포함).
- 예외: 널 칸만 선형으로 칠해지고, 나머지는 모두 박에 떨어지는 정밀 이징. 반짝임·광택·바운스·페이드 금지.
- 글꼴: 본문 Pretendard 한 가족(여러 굵기), 코드와 문자 칸만 JetBrains Mono. 한 글꼴 규칙을 바꾼 이유(한글 지원, '\0'·'0'·'l'·'1' 구별)를 기록.
- 자막: 화면 아래 띠가 아니라 왼쪽 페이지 1단의 레이아웃 자막(회색 머리말 + 굵은 진술), 단어별 클립 공개, 최소 1.8초 유지를 코드로 검사.
- 등장은 닦기·클립 공개, 삭제는 칼 자르기(선이 가로지르고 가운데로 접힘). 큰 숫자는 네 단계로 한 모듈씩 올라온다.
- 프로그래밍 용어를 읽는 동안에는 움직임을 멈춘다(진술마다 4~8초 유지).

[장면 — 89초, 120 BPM]
0–10.5   질문: "다섯 글자에 왜 여섯 칸일까?" 큰 5(글자 수)와 6(칸 수), 배열 6칸에 H e l l o, 마지막 칸이 빨간 '\0'
10.5–30  인덱스 0~5 → 널 종료 문자 → '\0'과 숫자 문자 '0'(값 0과 48) 비교 → '\'와 '0' 두 기호지만 한 칸 → 문자 코드 값(그림 8.6 재작도)
30–50    sizeof는 6칸 전체(위 괄호), strlen은 '\0' 앞까지 1~5를 세고 멈춤(아래 괄호), 실제 실행 결과 sizeof=6, strlen=5
50–65    printf %s: 재생선이 칸을 지나며 Hello 출력, 널 칸에서 멈춤. 가정: 널 칸을 칼로 지우면 회색 '?' 칸이 페이지 밖으로 이어짐(실행하지 않음, 정의되지 않은 동작)
65–89    char s[] = "AI"; 예측(? ? 멈춤 약 4초, 음악도 박자 틱만) → 3, 2와 실행 결과 → 정리 "칸 수 = 글자 수 + 1"(큰따옴표 초기화, 영문 ASCII 기준) → "문자열의 끝, \0"

[소리]
- 음성 없음(자막형). 임의 기계 TTS 금지.
- 120 BPM 음악을 새로 합성: 장마다 악기 하나씩(하이햇 → 킥 → 스네어·베이스 → 종소리), 예측 멈춤에서 드럼을 빼고 틱만.
- 효과음은 인쇄 재료처럼 건조하게: 글자 클랙, 숫자 쿵, 칼 소리, 괘선 '츠', 종이. 널 칸만 짧은 사인 글라이드로 '노래'한다.

[검증]
- gcc 실행 로그를 남기고 영상 속 콘솔·숫자와 대조한다.
- 완성 MP4 전체를 1초 간격 프레임으로 보고 라벨 잘림, 겹침, 오탈자, 빨강 사용 위치를 확인한다.
- 렌더링하지 않은 결과를 완성이라고 쓰지 않는다.
점검 프롬프트 (실제 수행)
렌더링한 정지 화면(전체 렌더 전)과 완성 MP4(1초 간격 전 프레임)를 보고 다음을 표로 보고하라.
1) 빨강이 널 종료 문자 칸 말고 다른 곳에 쓰였는지
2) 큰 숫자 두 개가 한 수(예: 56, 65, 32)처럼 읽히는지
3) 격자·괘선이 머리말 글자나 칸을 덮는지
4) 진술 문장이 다 보이기 전에 사라지거나 1.8초보다 짧은지
5) 영상 속 sizeof/strlen 값과 콘솔 줄이 gcc 실행 결과와 같은지
6) '교재 원문'과 '검증용 자체 코드', '실행하지 않은 가정'이 화면에서 구분되는지
문제마다 시간, 원인, 고칠 방법을 쓰고, 고치기 전에는 통과라고 쓰지 말라.
실제 수정 프롬프트 (실제 수행)
아래 세 가지를 고쳐 다시 렌더링하라. (1·2는 전체 렌더 전 정지 화면 점검, 3은 1차 완성 MP4의 1초 간격 전 프레임 점검에서 발견)
1. 큰 숫자 두 개(5와 6, 6과 5, 3과 2)가 나란히 서면 '56', '65', '32' 같은 한 수로 읽힌다
   → 두 숫자 사이(4단 시작 40 px 앞)에 검정 2 px 세로 괘선을 선형으로 그어 나누고, 숫자 아래 라벨(글자 수/칸 수, sizeof/strlen)을 22 px 회색에서 26 px 검정 SemiBold로 키워라.
2. 9.5초에 회색 단 격자가 위로 걷힐 때 머리말 글자 위에 그려진다
   → 격자 띠를 그리기 순서의 맨 아래 층으로 옮겨라.
3. 장면이 바뀌는 순간(10.5·14.5·19.5초 등) 앞 진술의 회색 머리말이 위로 나가는 동안 새 머리말이 같은 자리에서 올라와 두 줄이 겹쳐 보인다
   → 새 머리말을 1/8박(0.25초) 늦게 올려라. 본문 단어는 이미 0.25초 뒤에 시작하므로 그대로 둔다.
고친 뒤 같은 점검 프롬프트로 완성 MP4 전체 프레임을 다시 확인하라.
확장 프롬프트 (아직 실행하지 않음)
사례06과 같은 격자·색·글꼴 규칙으로 '크기를 직접 지정하는 경우'를 다룬 30초 짧은 영상을 만든다(교재 246~247쪽 4절).
char a[6] = "Hello";(딱 맞음), char b[10] = "Hello";(남는 칸), char c[5] = "Hello";(널 칸이 없음)를 나란히 놓는다.
c[5]는 C에서 오류 없이 컴파일되지만 널 종료 문자가 없어 문자열 함수에 넘기면 안 된다는 점을 보여 주고, 그 결과는 실행하지 않고 '정의되지 않은 동작'으로만 설명한다.
a, b의 sizeof와 strlen, c의 sizeof를 gcc로 실제 실행해 화면 값과 대조하라(사전 확인: a 6/5, b 10/5, c sizeof 5, gcc 13.3.0 -Wall -Wextra 경고 없음).
남는 칸은 회색 모듈로, 널 종료 문자는 빨강 하나로만 표시한다. 교재 원문과 자체 코드를 화면에서 구분하라.

7. 실제 영상과 대표 프레임

아래가 교재 245~247쪽으로 만든 영상입니다(1:29, 1920×1080, 24fps). 음성은 없고 화면 속 진술 문장이 자막 역할을 하며, 새로 합성한 음악과 효과음이 들어 있습니다. 위 2절의 원작 영상과는 주제도 그림도 다른 별개의 작품입니다.

왼쪽에 큰 숫자 5와 6, 오른쪽에 H e l l o와 빨간 널 문자 칸이 있는 화면
대표 프레임 01 · 9.5초 — 글자 수 5, 칸 수 6. 빨간 칸이 널 종료 문자입니다.
sizeof 괄호가 6칸 전체를, strlen 괄호가 앞 5칸을 묶고 실행 결과 sizeof=6, strlen=5가 표시된 화면
대표 프레임 02 · 46.5초 — sizeof는 6칸 전체, strlen은 '\0' 앞까지 1~5를 세고 멈춥니다. 콘솔 줄은 실제 실행 결과입니다.
char s[] = AI 의 세 칸 배열과 큰 숫자 3과 2, 실행 결과 sizeof=3, strlen=2가 표시된 화면
대표 프레임 03 · 76초 — 예측 문제 char s[] = "AI";의 답: 칸 수 3, 글자 수 2.
sizeof str = 6 Hello\012345멈춤 strlen(str) = 5 — '\0' 앞까지 gcc 13.3.0 실행: sizeof=6, strlen=5 (검증용 자체 코드)

자체 도식 2 · sizeof와 strlen 비교.

8. 검산, 오류, 연습

실행 검증 (gcc 13.3.0, -Wall -Wextra -std=c11)

/* 검증용 자체 코드 — 교재 원문 아님 */
#include <stdio.h>
#include <string.h>
int main(void) {
    char str[] = "Hello";
    printf("sizeof=%zu, strlen=%zu\n", sizeof str, strlen(str));
    return 0;
}
확인한 것실행 결과영상 속 표시
char str[] = "Hello";sizeof=6, strlen=5같음(장면 03)
char s[] = "AI";sizeof=3, strlen=2같음(장면 05)
각 칸의 값72 101 108 108 111 0같음(그림 8.6과도 같음)
'\0'과 '0'0과 48같음(장면 02)
함수 매개변수로 받은 경우sizeof p = 8(이 컴퓨터의 포인터 크기), strlen = 5메모로만 언급, 일반화하지 않음
널 문자 없는 배열을 %s로 출력실행하지 않음‘정의되지 않은 동작’으로만 설명

영상 검증은 실행 검증과 따로 했습니다. 완성 MP4를 처음부터 끝까지 1초 간격 89장으로 확인했고, 빨강이 널 칸 말고 다른 곳에 쓰이지 않았는지, 진술 문장이 다 읽히기 전에 사라지지 않는지(최소 1.8초는 코드로도 검사)를 봤습니다.

작업 중 실제로 고친 것

  • 큰 숫자 두 개가 나란히 서면 ‘56’, ‘65’처럼 한 수로 읽혔습니다. 두 숫자 사이에 세로 괘선을 긋고 아래 라벨을 키웠습니다.
  • 회색 단 격자가 걷힐 때 머리말 글자를 덮었습니다. 격자를 맨 아래 층으로 옮겼습니다.
  • 장면이 바뀌는 순간 회색 머리말 두 줄이 겹쳐 보였습니다(1차 완성본 점검에서 발견). 새 머리말을 0.25초 늦게 올리고 다시 렌더링했습니다.

연습

연습 1. char t[] = "C lang";의 sizeof와 strlen을 먼저 예측하고 직접 실행해 보세요. 교재 247쪽의 “최소 char str[7]” 설명과 비교합니다.

연습 1 답 확인

공백도 한 글자이므로 글자 수는 6, 널 종료 문자까지 7칸입니다. sizeof는 7, strlen은 6입니다.

연습 2. 다음 두 문장 중 틀린 것을 고르세요. ① '\0'은 백슬래시와 0, 두 칸을 쓴다. ② '\0'과 '0'은 값이 다르다.

연습 2 답 확인

①이 틀렸습니다. '\0'은 기호 두 개로 적지만 메모리에서는 값이 0인 문자 하나, 한 칸입니다. '0'의 값은 48입니다.

주의: 이 영상과 연습은 영문 ASCII 문자열 기준입니다. 한글은 UTF-8에서 한 글자가 여러 바이트일 수 있으므로 “글자 수 + 1 = 칸 수”를 그대로 적용하면 안 됩니다.

9. 출처와 권리 (확인일 2026-10-24)

  • 원본 스타일: Lemo-Opuscar by Lemomo / LemoLab — github.com/lemomo-ai/lemo-opuscar (작업 시점 커밋 413a6bd, swiss-motion 최종 변경 a401d6c). 코드·문서 MIT. 이번 영상은 ease.js 한 파일을 MIT 조건으로 사용했습니다.
  • 원본 시연 영상 Five Rules for a Poster: CC BY 4.0, 저작자 LemoLab. 이 글에서는 원본 주소로 연결만 했고 편집하지 않았습니다.
  • README 기준 라이브러리로 만든 영상은 만든 사람의 것입니다. 원작 데모의 글꼴(Archivo)·음악 샘플·음성·엔드카드는 쓰지 않았습니다.
  • 글꼴: Pretendard(SIL OFL 1.1, 길형진), JetBrains Mono(SIL OFL 1.1, JetBrains). 음악과 효과음은 새로 합성했습니다.
  • 교재: 기초 C언어 8장 245~247쪽(그림 8.6은 다시 그림). 검증 코드는 자체 작성.

댓글

이 블로그의 인기 게시물

📄 [제미나이 활용법 3편] PDF 보고서를 1분 안에 요약하는 방법

📄 [업무 자동화] 생성형 AI로 10초 만에 회의록 완성하는 법

[제미나이 활용법 2편] 복잡한 뉴스 기사, 5분 만에 회의 자료로 바꾸는 법