텍스트 애플리케이션에서 Carriage Return 사용하기

Unix를 비롯한 대부분의 시스템은 LF(\n, 0x0A)를 개행 문자로 사용하기 때문에 CR(\r, 0x0D)을 사용하는 경우가 거의 없다. 텍스트 애플리케이션에서 진행표시줄을 만드는 것이 진행표시줄을 만드는 것이 현대 컴퓨터에서 CR을 사용하는 거의 유일한 경우라고 볼 수 있다. CR을 사용하면 터미널에서 진행표시줄을 간단하게 구현할 수 있다.

위의 코드는 #과 ' '(공백 문자)로 진행표시줄을 그린다. 편의를 위해 진행표시줄의 길이는 20개로 고정했고, 전달받은 진행도에 따라 5%마다 #을 하나씩 더 그리는 방식으로 구현했다. 이런 식으로 CR을 이용해 진행표시줄을 그리는 경우 주의할 점은 세가지 있다.

첫번째 주의할 점은 진행표시줄을 stdout이 아닌 stderr에 그려야 한다는 것이다. stdoutstderr의 큰 차이 중 하나는 stdout은 출력을 즉시 화면에 보여주지 않고 버퍼링한다는 것이다. 보통 stdout은 개행문자가 있을 때까지 출력을 버퍼링한다. 이 때문에 개행문자를 쓰지 않고 화면을 계속 갱신하는 진행표시줄을 stdout에 출력하면, 진행표시줄이 완료될 때까지 화면이 갱신되지 않을 것이다. 만약 stdout을 써야 하는 이유가 있다면, flush(stdout) 함수를 호출해 수동으로 버퍼를 출력시켜야 한다.

두번째 주의할 점은 다음에 출력할 문자열의 길이가 이전에 출력한 문자열보다 짧으면 안 된다는 것이다. CR은 커서를 줄의 시작으로 옮길 뿐 현재 줄을 지우는 것이 아니다. 길이가 고정 된 진행표시줄과 같은 경우는 이런 걱정을 안 해도 되지만, 다양한 문자열을 같은 줄에 반복해서 출력시키는 경우는 보다 복잡한 컨트롤 시퀀스를 이용해 현재 줄을 지우거나 공백 문자 등을 이용해 남은 글자를 지워야 한다.

마지막 주의할 점은 진행표시줄을 갱신하는 중에 다른 문자열을 출력하면 안 된다는 것이다. 위의 코드는 진행표시줄이 완료될 때까지 진행표시줄만 그린다는 가정하에 간단하게 작성 된 코드다. 중간에 다른 문자열이 출력되면 원하던 것과 전혀 다른 결과가 나올 것이다.

진행표시줄이 같은 같은 위치를 반복해서 수정해야 하는 것은 컨트롤 시퀀스를 이용해 더 완벽하게 구현할 수 있다. 하지만 간단한 데이터 처리 프로그램을 구현할 때 컨트롤 시퀀스까지 이용하는 것은 닭잡는데 소잡는 칼을 쓰는 꼴이 될 수 있다. 간단한 프로그램의 진행도를 표시하기 위한 용도로는 CR을 사용하는 것만으로 간단하게 구현할 수 있다.

댓글

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

RAII는 무엇인가

[Python] cache 데코레이터로 최적화하기

[Web] SpeechSynthesis - TTS API