type="nal"

[JS] 자바스크립트 표준입출력 readline, fs 본문

Programming Language/JavaScript

[JS] 자바스크립트 표준입출력 readline, fs

nalmi 2026. 1. 28. 22:31

자바스크립트 코테에서 데이터를 입력받는 방식엔 readline과 fs 두가지가 있다.

 

1. readline 모듈

readline 모듈을 이용해 입력을 한 줄씩 받는 방식이다.

 

예시로 풀어볼 문제: https://www.acmicpc.net/problem/10951

두 수를 입력받아 합을 출력하는 문제. 따로 테스트케이스 개수는 주어지지 않는다.

const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let result = [];

rl.on("line", (line) => {
  const [a, b] = line.split(" ").map(Number);
  result.push(a + b);
}).on("close", () => {
  console.log(result.join("\n"));
});

readline의 line 이벤트는 데이터가 한 줄 들어올 때마다 한 번씩 실행된다.

그래서 입력된 줄 개수만큼 input 배열에 결과값을 저장할 수 있다.

그리고 입력 스트림이 끝나면 자동으로 'close' 이벤트를 발생시킨다.

 

예제 인풋으로 작성중인 코드를 테스트하려면 엔터를 쳐도 입력이 종료되지 않기 때문에 아래처럼 조건문을 추가해줄 수 있다.

const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

let result = [];

rl.on("line", (line) => {
  if (!line) { // 입력이 비어있거나(Enter만 쳤거나) 데이터가 없으면
    rl.close();
    return;
  }
  
  const [a, b] = line.split(" ").map(Number);
  result.push(a + b);
}).on("close", () => {
  console.log(result.join("\n"));
});

혹은 엔터를 치고 윈도우에서: ctrl + z

맥에서: ctrl + d

로 입력 명령어를 종료하면 된다. (이때 결과에 ^D 이런 코드 안뜨게 하려면 stty -echoctl 명령어 치면 그냥 종료가 된다.)

 

 

2. fs 모듈

fs는 readline처럼 한 줄씩 이벤트를 기다리지 않고, 파일 전체를 통째로 읽어서 처리하는 방식으로
속도가 더 빠르고 편리하다는 장점이 있다.
const fs = require("fs");

// 전체 입력을 한꺼번에 읽어오기
const input = fs.readFileSync(0).toString().trim().split("\n");

// 개수가 없으므로 그냥 배열의 처음부터 끝까지 순회하면 됩니다.
input.forEach((line) => {
  if (line) {
    // 빈 줄이 아닌 경우에만 실행
    const [a, b] = line.split(" ").map(Number);
    console.log(a + b);
  }
});
  • 이때 0은 표준 입력(stdin)의 파일 설명자(file descriptor)이다.
  • readFileSync는 데이터를 Buffer(0과 1로 된 바이너리 데이터) 형태로 가져온다.
    우리가 읽을 수 있는 문자열로 바꾸기 위해 toString()을 붙여줌

2-1) 주의사항

입력 파일 끝에는 보통 눈에 보이지 않는 줄바꿈(\n)이나 공백이 하나 더 붙어 있는 경우가 많다.
trim() 없이 split('\n')을 하면, 배열의 마지막 요소에 빈 문자열("")이 들어가서 정렬이나 계산 시 에러날 수 있기때문에 trim()은 필수적으로 붙여줄것

 

2-2) 자주 쓰는 입력 가공 패턴

① 한 줄에 값이 여러 개 있을 때 (예: 1 2)

const [a, b] = fs.readFileSync(0).toString().trim().split(' ').map(Number);

 

② 여러 줄에 값이 있을 때 (예: 첫 줄 N, 나머지 데이터)

const input = fs.readFileSync(0).toString().trim().split('\n');
const N = Number(input[0]);
const data = input.slice(1); // 1번 인덱스부터 끝까지 복사

 

③ 한 줄에 하나씩 숫자가 수만 개 있을 때

const numbers = fs.readFileSync(0).toString().trim().split('\n').map(Number);
 

 

 

 

3. fs와 readline 비교

특징 fs.readFileSync readline
속도 매우 빠름 (파일을 통째로 읽음) 비교적 느림 (줄 단위로 처리)
난이도 매우 쉬움 (동기적 실행) 조금 복잡 (비동기 이벤트 방식)
메모리 한 번에 다 읽어서 메모리를 점유함 메모리를 아껴 쓸 수 있음

fs를 사용하면 코드 길이와 속도가 짧아지고, but 메모리 제한이 빡빡하거나 런타임에러가 뜨는 경우 readline 모듈을 사용하면 된다.