Node.js 코딩 테스트 문제를 풀다 보면 꼭 나오는 코드가 있다.
`fs.readFileSync(0)`그냥 외워서 써보기도 했지만,
'왜 0일까?', '왜 split("\n")을 꼭 써야 하지?'가 반복적으로 문제를 풀면서 궁금해졌다.
이 코드가 실제로 어디서 입력을 읽는지, 어떤 형태로 들어오는지(Buffer),
그리고 split("\n")을 왜 붙여야 줄 단위 입력이 제대로 되는지 파봤다.
요약
stdin = Standard Input (표준 입력)
프로그램이 '입력'을 받을 때 사용하는 기본 통로이다.
Node.js에서는 fs.readFileSync(0)이 바로 이 표준 입력을 읽는 것이다.
즉, `fs.readFileSync(0)`은 파일 디스크립터(File Descriptor) 0번(stdin)을 읽는 코드이다.
🔍 한 문장 정리
Node.js에서 `fs.readFileSync(0)`은 표준 입력 전체를 버퍼로 읽고, `.toString()`으로 문자열화한 뒤, `.split("\n")`을 통해 줄 단위로 구분해야 여러 줄 입력을 올바르게 다룰 수 있게 한다.
1. 파일 디스크립터(File Descriptor)와 stdin(Standard Input)의 관계
운영체제는 입출력을 ‘파일’처럼 다루기 때문에 각 통로에는 고유 번호(FD, File Descriptor)가 부여하여 파일 대신 '표준 입력' 통로를 읽도록 하는 것이다.
| fs.readFileSync(0)의 번호 의미 | |
| 0 | stdin (표준 입력, Keyboard 등) |
| 1 | stdout (표준 출력, console.log 등) |
| 2 | stderr (표준 에러) |
2. Buffer 형태로 입력이 들어온다
Node.js는 I/O를 빠르게 처리하기 위해, 모든 입력 데이터를 2진(binary) 형태로 일단 메모리에 저장한다. 그것이 바로 Buffer(버퍼) 이다.
예를 들어 아래처럼 입력을 받았다고 가정 해본다.
C
89.84336
234.5678
이 입력을 `fs.readFileSync(0)`으로 읽으면 실제 내부엔 이렇게 저장된다.
<Buffer 43 0a 38 39 2e 38 34 33 33 36 0a 32 33 34 2e 35 36 37 38>
여기서
- 43은 'C'
- 0a는 줄바꿈(\n)
38은 '8'
… 이런 식으로 아스키코드 값이 들어있다.
3. `.toString()` : 버퍼 → 문자열
버퍼를 문자열로 바꾸면 이렇게 된다.
"C\n89.84336\n234.5678"
겉보기엔 줄이 바뀐 것 같지만, 실제로는 \n이 포함된 하나의 긴 문자열이다.
4. `.trim()` : 앞뒤 공백 제거
`.trim()`은 문자열 양 끝의 공백·줄바꿈을 제거한다. 그리고 중간의 \n은 그대로 남는다.
"C\n89.84336\n234.5678"
5. `.split("\n")` : 줄 단위로 나누기
`.split("\n")`은 문자열을 줄바꿈(\n) 기준으로 자르게 된다. 즉, 사용자가 친 엔터 기준으로 배열이 만들어지는 것이다.
"C\n89.84336\n234.5678".split("\n")
→ ["C", "89.84336", "234.5678"]
6. `.split("\n")`이 없을 때는?
`.split("\n")`을 빼면 이렇게 된다.
"C\n89.84336\n234.5678"
이건 하나의 문자열이 되어,
input[0]은 "C",
input[1]은 "\n",
input[2]는 "8" 처럼 문자 단위로만 접근이 가능하게 된다.
즉, '줄'의 개념이 사라지는 것이다.
7. 실제 입출력 순서 요약
const fs = require("fs");
let n = fs.readFileSync(0).toString().trim().split("\n");
let c = n[0]; // 문자
let a = Number(n[1]); // 문자열 → 숫자
let b = Number(n[2]); // 문자열 → 숫자
console.log(c);
console.log(a.toFixed(2)); // 소수 둘째 자리까지 반올림
console.log(b.toFixed(2));
입력이 다음과 같다면:
C
89.84336
234.5678
실행 과정은 아래와 같은 흐름을 보이게 된다.
| 단계 처리 내용 결과 | ||
| `fs.readFileSync(0)` | 표준 입력 전체를 Buffer로 읽음 | <Buffer ...> |
| `.toString()` | Buffer → 문자열 | "C\n89.84336\n234.5678" |
| `.trim()` | 앞뒤 공백 제거 | "C\n89.84336\n234.5678" |
| `.split("\n")` | 줄 단위 분리 | ["C", "89.84336", "234.5678"] |
| `Number()`, t`oFixed()` | 각 줄 데이터 변환 및 출력 | "C", 89.84, 234.57 |
비교 요약
구분 `split("\n")` 있음 vs. `split("\n")` 없음
| 데이터 형태 | 배열 (각 줄이 요소) | 하나의 문자열 |
| 예시 값 | ["C", "89.84336", "234.5678"] | "C\n89.84336\n234.5678" |
| 접근 방식 | `n[0]` → 첫 줄, `n[1]` → 둘째 줄 | `n[0]` → 문자 'C', `n[1]` → '\n' |
| 사용 목적 | 여러 줄 입력 | 한 줄 입력 |
| 장점 | 줄 단위로 쉽게 접근 가능 | 문자 단위 처리 가능 (특수 경우) |
결론
`fs.readFileSync(0)`은 표준 입력(stdin, 0번 파일 디스크립터)을 버퍼 형태로 읽어오는 코드이다.
Node.js는 줄바꿈을 `\n` 문자로 포함한 하나의 문자열로 반환하므로, 줄 단위 입력을 처리하려면 반드시 `.split("\n")`이 필요한 것이다.
즉, '사용자가 엔터로 구분한 입력'을 '프로그램이 배열로 구분해 다루게 만드는' 핵심 단계가 바로 `.split("\n")` 이라는 점이다!
참고자료
https://nodejs.org/api/fs.html#fsreadfilesyncpath-options
File system | Node.js v25.0.0 Documentation
File system# Source Code: lib/fs.js The node:fs module enables interacting with the file system in a way modeled on standard POSIX functions. To use the promise-based APIs: import * as fs from 'node:fs/promises';const fs = require('node:fs/promises');copy
nodejs.org
https://nodejs.org/api/process.html#processstdin
Process | Node.js v25.0.0 Documentation
Process# Source Code: lib/process.js The process object provides information about, and control over, the current Node.js process. import process from 'node:process';const process = require('node:process');copy Process events# The process object is an inst
nodejs.org
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split
String.prototype.split() - JavaScript | MDN
If separator is a string, an Array of strings is returned, split at each point where the separator occurs in the given string. If separator is a regex, the returned Array also contains the captured groups for each separator match; see below for details. Th
developer.mozilla.org
https://nodejs.org/api/buffer.html
Buffer | Node.js v25.0.0 Documentation
Buffer# Source Code: lib/buffer.js Buffer objects are used to represent a fixed-length sequence of bytes. Many Node.js APIs support Buffers. The Buffer class is a subclass of JavaScript's class and extends it with methods that cover additional use cases. N
nodejs.org
