본문 바로가기

프로그래밍 언어 정리/기초 다지기

[기초 다지기 - 1] EOF

[Input]
ABCDAKD
129322 
34
가나다걖쓨믦
abciekld
^Z (입력 종료)

 

Input은 다음과 같고 Output은 없습니다.

 

지난번 빠른 입출력을 다를 때는, 입력이 10 X 10으로 정해졌다는 가정 하에 코드를 작성하였으나, 이번에는 입력의 길이를 모른다는 가정 하에 EOF를 사용하여 코드를 작성하였습니다.

 


[Java]

 

> EOF

 

package jv;

import java.io.*;

public class main1{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        String s;

        while (true) {
            s = br.readLine();
            if (s == null) break;
            sb.append(s).append('\n');
        }
        
        System.out.println(sb.toString());
    }
}

 

무한루프를 이용하여 무한정 입력을 받습니다. 받아들인 입력이 null(입력 종료)인 경우 while문을 탈출하도록 하면 끝입니다.

여기서 약간의 코드 최적화가 가능합니다.

 


> EOF 2

 

import java.io.*;

public class main1{
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        String s;

        while ((s = br.readLine()) != null) {
            sb.append(s).append('\n');
        }
        
        System.out.println(sb.toString());
    }
}

 

코드에 약간의 최적화를 가했습니다. if문 없이 while 조건문에서 s를 받음과 동시에 null 검사를 진행합니다.

생각보다 유용한 스킬이니 알고 있는 것이 좋습니다.

 


[C++]

 

> EOF 1

 

#include <iostream>
using namespace std;

int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    string s;

    while (1) {
        cin >> s;
        if (cin.eof()) break;
        cout << s << '\n';
    }
    
    return 0;
}

 

C++에서 사용하는 가장 기본적인 EOF입니다. scanf를 사용한 방식도 존재하나, C++에만 있는 cin을 사용한 방식을 소개합니다.

무한루프를 돌다가 입력이 종료됨(^Z)을 cin이 인식하면, break 합니다.

 


> EOF 2

 

#include <iostream>
using namespace std;

int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    
    string s;

    while (!(cin >> s).eof()) {
        cout << s << '\n';
    }
    
    return 0;
}

 

Java에서 사용한 최적화를 이용하여 작성하였습니다. Java와 마찬가지로 while 문에서 s를 받음과 동시에 cin.eof()로 ^Z를 검사합니다.

C++에서는 처음 사용해봤는데 진짜 될 줄은 몰랐습니다. 

 


> EOF 3

 

#include <iostream>
using namespace std;

int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    while (1) {
    	string s;
        cin >> s;
        if (s.empty()) break;
        cout << s << '\n';
    }
    
    return 0;
}

 

cin.eof()가 아닌 string.empty()로 짠 EOF 코드입니다. 

 

아래는 해당 코드의 흐름입니다.

 

  1. s 선언. 현재 s는 NULL 상태입니다.
  2. s에 값을 계속 넣다가 ^Z가 들어오게 되면, cin은 더 이상 동작하지 않습니다.
  3. cin이 동작하지 않았으므로 s는 NULL 상태입니다. (주의할 점은 cin이 s에 NULL을 넣은 것이 아닙니다. cin은 ^Z이 들어온 순간 멈췄고 s에 아무 영향을 주지 않았습니다. Java의 BufferedReader.readLine()이 ^Z을 받고 null을 넣던 것과는 다릅니다.)
  4. s는 NULL이므로 s.empty() == true이고 while문을 탈출하게 됩니다.

 


[Python]

 

> EOF

 

import sys

br = sys.stdin
bw = sys.stdout

for s in br.readlines():
    bw.write(s)

br.close()
bw.flush()
bw.close()

 

일반적으로 python에서 EOF는 try를 사용하나, 빠른 입출력(sys.stdin)을 사용할 경우는 다릅니다. 모든 입력을 받아오는 stdio.readlines()를 이용하여 반복문으로 인자에 한 줄씩을 받아옵니다. 위 방법으로 자연스럽게 EOF가 해결됩니다.

 


 

> EOF 2

 

while 1:
    try:
        s = input()
        print(s)
    except:
        break

 

참고용으로 작성한 try문을 이용한 코드입니다.