[CPP-00] Megaphone! CPP 표준입출력

CPP의 std i/o stream, namespace 에 대한 기본적인 정리

[CPP Module00 / EX00: Megaphone 과제 소개]

Just to be sure that everybody is awake, write a program that has the following behavior:

$>./megaphone "shhhhh... I think the students are asleep..."
SHHHHH... I THINK THE STUDENTS ARE ASLEEP...

$>./megaphone Damnit " ! " "Sorry students, I thought this thing was off."
DAMNIT ! SORRY STUDENTS, I THOUGHT THIS THING WAS OFF.

$>./megaphone
* LOUD AND UNBEARABLE FEEDBACK NOISE *

$>
  • 소문자를 대문자로 변경

  • 쌍따옴표 문자열 안의 공백도 그대로 출력

  • 인자가 없을 시 에러메세지 출력

1. CPP 표준입출력

#include <iostream>

int main() {
  std::cout << "Hello, World!!" << std::endl;
  return 0;
}

C에서 <stdio.h> 라이브러리를 사용했다면, CPP에는 iostream 객체지향 라이브러리가 존재한다. CPP가 기본적으로 객체지향 언어이기 때문에 표준 입출력을 담당하는 함수들이 모두 객체로 정의되어 있다. 스트림이라는 용어의 의미가 궁금했는데, 여러 장치에 입출력 작업이 실행되는 것을 '추상화' 하여 나타낸 것이라고 한다. 모니터, 키보드, 파일, 네트워크 등과 프로그램을 연결해주는 중간 매개자 역할 느낌. C 과제를 할 때 임시 버퍼를 만들어 데이터를 전달했던 것을 떠올렸는데, 실제로 스트림은 내부에 버퍼(임시 메모리 공간)를 가지고 있다고 한다.

대부분의 C++ 프로그램은 입력 시에는 사용자가 Enter 키를 누르면 입력 버퍼를 비우고, 출력 시에는 개행 문자를 전달받으면 출력 버퍼를 비우게 된다고 한다.

표준 입출력 라이브러리(iostream) 의 구성 요소들은 여기에 잘 정리되어 있다. 출력을 담당하는 cout 객체, 다음 과제에서 사용할 endl 이나 setw 같은 객체 조작자(Manipulator) 함수들도 정리되어 있으니 앞으로도 몇 번 들러 참고할 것 같다.

2. namespace

CPP 표준 라이브러리에 존재하는 모든 변수나 함수들(객체)는 std 표준 네임스페이스에 포함되어 있다. 그래서 표준 라이브러리를 사용할 때는, 즉 출력을 위한 cout 객체를 사용하기 위해서는 std::cout 처럼 네임스페이스를 붙여 사용해야한다. 그렇다면 네임스페이스가 뭘까? 이름에서 뜻을 유추할 수 있듯이 정의된 객체나 함수의 소속을 의미한다. namespace를 사용하면 중복된 이름의 함수끼리도 접두어만 다르게 해서 구분지어 사용할 수 있다는 장점이 있다.

2.1. namesapce 정의 방법

namespace tmp {
    int foo();
    void bar();
  int func() {
      foo();  
  }
}

int func() {
  tmp::foo();
}
  • tmp 이름공간 안에서 foo()를 호출하면 알아서 tmp:foo()를 호출하게 된다.

  • 다른 곳에서 tmp 이름공간의 foo()를 호출하고 싶다면 함수 앞에 tmp:: 를 명시해야한다.

2.2. using namespace

#include <iostream>
using namespace std;

int main() {
  cout << "Hello, World!!" << endl;
  return 0;
}
  • 한 파일 내에서 한 이름공간을 계속 사용하고 싶다면 using namespae 를 사용하는 방법이 있다.

  • 그러나 권장되지 않는 방법이다. 42 과제에서도 사용을 금지하고 있다.

  • CPP가 지원하는 수 많은 템플릿과 라이브러리에 이미 존재하는 객체들과의 혹시 모를 이름충돌로부터 프로그램을 보호하기 위해 그냥 namespace를 명시해주는 것이 낫다.

Last updated