readFileSync 를 이용한 입력

2025. 4. 11. 14:52·JavaScript

파일시스템을 이용한 입력 받기

 

const fs = require("fs");

let n = Number(fs.readFileSync(0).toString().trim());

 


require("fs") :

FileSystem 의 약자.


파일 시스템 모듈 안에는 컴퓨터의 파일 시스템과 상호작용할 수 있는 다양한 기능(함수)들이 들어있습니다. 
파일 읽기 (readFile, readFileSync 등)
파일 쓰기 (writeFile, writeFileSync 등)

 

require('모듈_이름')

  • JavaScript 파일(모듈)이나 내장 모듈, 설치된 패키지의 기능을 불러옵니다.

cpp의 #include, java의 import로 이해하면 될 듯 하다.


let n = Number(fs.readFileSync(0).toString().trim());

 

.readFileSync(0):

 

  • fs.readFileSync: 앞서 설명한 fs 모듈의 동기적 파일 읽기 함수입니다.
  • 인자 0: 파일 경로 대신 숫자 0을 인자로 사용했습니다. 이는 파일 디스크립터(File Descriptor) 0을 의미하며, 이는 표준 입력(Standard Input, stdin)을 가리킵니다.
    • 왜 0을 사용하는가?: 주로 경진 프로그래밍이나 간단한 명령줄 도구에서 사용자의 키보드 입력을 직접 받거나, 다른 명령어의 출력을 파이프(|)로 연결받아 처리하기 위해 사용됩니다. 특정 파일 이름을 지정하는 대신 약속된 번호 0으로 표준 입력을 읽는 것입니다.
  • 출력값 (반환값): 표준 입력으로부터 읽어들인 데이터 전체를 Buffer 객체 형태로 반환합니다. 이진 데이터이므로 바로 문자나 숫자로 사용할 수 없습니다.

 

.toString():

  • 호출 대상: fs.readFileSync(0)이 반환한 Buffer 객체.
  • 이유: Buffer는 이진 데이터 덩어리입니다. 사용자가 숫자를 입력했더라도(예: '123'), Buffer에는 '1', '2', '3' 각 문자에 해당하는 바이트 코드가 저장되어 있습니다. 이를 JavaScript의 Number() 함수가 이해할 수 있는 문자열 형태로 바꿔줘야 합니다. .toString() 메서드가 이 역할을 하여 Buffer를 문자열 (기본적으로 UTF-8 인코딩)으로 변환합니다. 예를 들어, Buffer에 '1', '2', '3', '\n' 의 바이트 코드가 있었다면, 문자열 "123\n" 이 됩니다.

 

3. .trim() 부분:

타 언어와 같다. 문자열 끝의 개행 문자를 제거하기 위함.
앞쪽 끝과 뒷쪽 끝의 모든 공백과 줄바꿈 문자를 제거한다.

 

사용자가 표준 입력(키보드)으로 값을 입력하고 Enter 키를 누르면, 입력된 값 끝에 개행 문자(줄바꿈 문자, \n)가 함께 들어오는 경우가 일반적입니다. 또한, 사용자가 실수로 값 앞이나 뒤에 공백을 입력할 수도 있습니다. 만약 "123\n" 이나 " 123 " 같은 문자열을 바로 Number() 함수로 변환하려고 하면, 숫자 부분이 아닌 문자(개행, 공백) 때문에 NaN (Not-a-Number)이 반환될 수 있습니다. .trim() 메서드는 문자열의 양쪽 끝에 있는 모든 공백과 줄바꿈 문자를 제거하여 "123" 과 같이 순수한 내용만 남겨줍니다. 이것이 숫자 변환 전에 .trim()을 사용하는 핵심 이유입니다.

 


여러 줄 입력 받기

아래 예제는 두 줄에 걸쳐 이름과 나이를 입력받은 뒤, 해당 정보를 출력하는 간단한 예시입니다.

 
const fs = require("fs");
// split 함수를 이용해 여러 줄 입력받기
let input = fs.readFileSync(0).toString().trim().split('\n');

// 첫 번째 줄(input[0])에 이름 입력받기
let name = input[0];

// 두 번째 줄(input[1])에 나이 입력받기
let age = Number(input[1]);

// 결과 출력
console.log(name + " 님의 나이는 " + age + " 살입니다.");

 

 

예시 입력(사용자 입력 예시):

 
(첫 번째 줄) Teddy
(두 번째 줄) 20

예시 출력(콘솔 결과):

 
Teddy 님의 나이는 20 살입니다.

 

공백이 포함된 입력 처리

  • readFileSync() 함수는 사용자의 모든 입력을 한번에 받으므로, 마찬가지로 공백을 포함한 입력을 받을 때에는 공백 문자 ( )을 기준으로 입력을 나누어야 합니다.
  • 예를 들어, 이름과 성이 구분된 문자열을 입력받아 처리해 봅시다.
 
const fs = require("fs");
// split 함수를 이용해 공백을 나누어 입력받기
let input = fs.readFileSync(0).toString().trim().split(' ');

let firstName = input[0];
let familyName = input[1];

console.log(firstName + " 님의 성은 " + familyName + " 입니다.");

예시 입력:

 
길동 홍

예시 출력:

 
길동 님의 성은 홍 입니다.

 

즉,

split을 기준으로 입력 데이터를 바로 나누고 나눈 데이터를 배열 데이터로 저장



fs.readFileSync(0) 두 번 호출 시 주의점

Node.js로 코딩 테스트 문제를 풀거나 간단한 명령줄 도구를 만들 때, 표준 입력(Standard Input, stdin)으로부터 사용자 입력을 받아야 하는 경우가 많습니다. 이때 fs 모듈의 readFileSync 함수를 사용하는 간편한 방법이 있죠. 특히 fs.readFileSync(0)은 표준 입력(파일 디스크립터 0번)을 직접 읽는 코드로 자주 등장합니다.

JavaScript
 
// 예시: 표준 입력을 읽는 코드 (흔히 사용됨)
const fs = require('fs');
const input = fs.readFileSync(0).toString().trim();
console.log("입력받은 내용:", input);

그런데 만약 여러 줄의 입력이나 여러 종류의 입력을 받아야 할 때, 실수로 fs.readFileSync(0)를 여러 번 호출하면 어떻게 될까요? 예를 들어 첫 줄에서 데이터 개수 N을 읽고, 다음 줄에서 N개의 데이터를 읽으려고 아래처럼 코드를 작성하면 문제가 발생합니다.

JavaScript
 
const fs = require('fs');

// !!! 잘못된 예시 !!!
// 첫 줄 (개수 N) 읽기 시도
const n_string = fs.readFileSync(0).toString().trim();
// 두 번째 줄 (데이터 배열) 읽기 시도
const data_string = fs.readFileSync(0).toString().trim(); // <-- 문제 발생 지점!

// 이후 로직... (data_string이 비어있거나 예상과 다를 수 있음)

결론부터 말하면, 위와 같이 fs.readFileSync(0)를 같은 스크립트 내에서 여러 번 호출하여 표준 입력을 순차적으로 읽으려는 시도는 일반적으로 올바르게 동작하지 않습니다.

 

1. 표준 입력(stdin)은 '스트림(Stream)'입니다.

표준 입력은 키보드 입력이나 파이프(|)를 통해 전달되는 데이터의 **흐름(stream)**입니다. 스트림은 데이터가 한 방향으로 흐르는 통로와 같습니다. 한 번 흘러가거나 읽어들인 데이터는 기본적으로 다시 되돌려서 읽을 수 없습니다.

 

2. fs.readFileSync(0)의 동작 방식

  • fs.readFileSync(0)는 표준 입력 스트림에서 현재 위치부터 데이터의 끝(EOF - End Of File)까지 모든 내용을 동기적으로 읽어들입니다.
  • 중요한 것은, 데이터를 읽으면 스트림의 내부적인 읽기 위치가 데이터의 끝으로 이동한다는 점입니다. 즉, 스트림의 내용을 **소진(consume)**합니다.

3. 두 번 호출 시 발생하는 문제

  1. 첫 번째 fs.readFileSync(0) 호출: 표준 입력 스트림의 시작부터 끝(EOF)까지 모든 데이터를 읽습니다. 예를 들어 사용자가 두 줄을 입력했다면, 그 두 줄의 내용 전체가 읽혀지고 스트림의 읽기 위치는 파일의 끝(EOF)을 가리키게 됩니다.
  2. 두 번째 fs.readFileSync(0) 호출: 다시 표준 입력 스트림에서 데이터를 읽으려고 시도합니다. 하지만 이미 스트림은 첫 번째 호출에서 끝까지 다 읽힌 상태(EOF)입니다. 따라서 더 이상 읽을 데이터가 남아있지 않습니다.
  3. 결과: 두 번째 호출은 대부분 빈 데이터(길이가 0인 Buffer 또는 빈 문자열)를 반환하게 됩니다. 이 빈 데이터를 가지고 .split()이나 Number() 같은 후속 처리를 하려고 하면 에러가 발생하거나, NaN, undefined 같은 예상치 못한 결과를 얻게 되어 프로그램이 제대로 동작하지 않습니다.

 

fs.readFileSync(0)을 표준 입력 처리에 사용하는 것은 코딩 테스트 환경의 특성(전체 입력 한 번에 주어짐, 동시성 불필요)에 잘 맞아 떨어져서 마치 '일회용 입력 처리'처럼 보이는 것입니다.

하지만 fs.readFileSync 함수 자체는 파일 읽기에도 사용되며, 그 핵심 특징이자 (상황에 따른) 단점은 동기적으로 작동하여 코드를 멈춘다는 점입니다. >> 동기적 특징을 가지고 있어, 입력 받기 전까진 메인 스레드가 멈춘다. 시스템 초반에 파일을 입력받고 시작하는 경우 좋음

 

저작자표시 (새창열림)

'JavaScript' 카테고리의 다른 글

map을 이용한 배열의 각 요소 접근  (0) 2025.04.13
자바 스크립트의 String  (0) 2025.04.12
console.log의 인자  (0) 2025.04.11
동등 연산자, 일치 연산자  (0) 2025.04.11
자바스크립트의 자료형  (0) 2025.04.10
'JavaScript' 카테고리의 다른 글
  • map을 이용한 배열의 각 요소 접근
  • 자바 스크립트의 String
  • console.log의 인자
  • 동등 연산자, 일치 연산자
람팜팜~
람팜팜~
:)
  • 람팜팜~
    RumPumPum
    람팜팜~
  • 전체
    오늘
    어제
    • 전체 (123)
      • 🎵 일상 (2)
      • JAVA (5)
        • 김영한의 자바 입문 (3)
      • JavaScript (12)
      • ---------------------------.. (0)
      • [게임 개발] 포트폴리오 (2)
        • RPG (1)
        • 슈터-플랫포머 (1)
      • [게임 개발] 개발 일지 (28)
        • RPG (25)
        • TopDownProject (3)
      • [게임 개발] 언리얼엔진 공부 (9)
        • 이득우의 언리얼 프로그래밍 Part.1 (6)
        • 이득우의 언리얼 프로그래밍 Part.2 (1)
        • 개인 메모 (2)
      • [게임 개발] 알고리즘 공부 (60)
        • 프로그래머스 (8)
        • 백준 (52)
        • 개인 메모 (0)
      • [게임 개발] CPP 공부 (2)
        • 이것이 C++ 이다 (1)
        • Effective C++ (0)
        • Effective Modern C++ (0)
        • 홍정모 그래픽스 새싹코스 (1)
      • [게임 개발] CS 공부 (3)
  • 블로그 메뉴

    • 링크

      • Github
    • 공지사항

    • 인기 글

    • 태그

      그리디
      context switching
      메모리구조
      dp
      문자열
      스레드
      해시
      역참조
      참조자
      데드락
      프로세스
      누적합
      슬라이딩 윈도우
      dfs
      우선순위 큐
      투포인터
      브루트포스
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    람팜팜~
    readFileSync 를 이용한 입력
    상단으로

    티스토리툴바