----------------
title : C++ 레퍼런스 - istream::sentry 클래스
cat_title : istream::sentry
ref_title : sentry, istream::sentry
publish_date : 2019-04-19
path : /C++ Reference/iostream
--------------

##@ cpp-ref-start

#@ istream::sentry

`<istream>` 에 정의됨

```cpp-formatted
class sentry;
```

`basic_istream::sentry` 객체는 `std::basic_istream` 에서 입력을 수행하는 멤버 함수들에 의해 생성되는 객체이다. `sentry` 객체의 생성자는, 입력 스트림을 다음 같은 방법으로 준비한다.\sidenote{sentry 라는 단어의 원래 뜻은 보초 이다.}

* 스트림이 이미 `fail` 상태 인지 확인한다.
* `tie()` 된 출력 스트림을 `flush` 한다.
* `noskipws` 플래그가 설정되어 있지 않다면, 접두에 등장하는 공백 문자들을 무시한다.
* 그 외에 여러가지 구현에 따라 다른 일들을 수행한다.

`sentry` 객체가 소멸 될때, 필요한 **청소** 작업을 수행하는데 이는 입력 연산 중에 예외가 발생하더라도 입력 스트림을 안전하게 마무리 짓기 위함이다.


### 멤버 함수들

* 생성자 : `sentry` 객체를 생성하며, 모든 준비 작업들이 여기에서 수행된다.

```cpp-formatted
explicit sentry(std::basic_istream<CharT, Traits>& is, bool noskipws = false);
```

`sentry` 객체의 생성자는 위와 같은 꼴이다. 만일 `is.good()` 이 `false` 라면, `is.setstate(failbit)` 를 호출한 후에 리턴한다. 그 다음, `is.tie()` 을 확인해서 널 포인터가 아니라면, `is.tie()->flush()` 를 호출해서 출력 스트림과 동기화를 수행한다. 이 과정은 `is.tie()` 의 `put area` 가 0 이라면 생략된다.

그 후에 `noskipws` 가 0 이거나 `is.flags() & ios_base::skipws` 가 0 이 아니라면, 첫 공백 문자가 나타나기 전 까지 모든 공백 문자를 날려버린다. 만일 `is.rdbuf()->sbumpc()` 나 `is.rdbuf()->sgetc()` 가 `traits::eof()` 를 리턴한다면, `setstate(failbit | eofbit)` 를 호출한다.

* 소멸자 : 모든 입력이 끝난 후에, 혹은 예외가 발생 하였을 때 안전하게 스트림 객체를 마무리 짓는다.
* `operator=` : 지워짐; `sentry` 객체는 복사 생성이 불가능하다.
* `operator bool` : 준비 과정이 성공적이였는지 확인한다.

### 실행 예제

```cpp-formatted
#include <iostream>
#include <sstream>

struct Foo {
  char n[5];
};

std::istream& operator>>(std::istream& is, Foo& f) {
  std::istream::sentry s(is);
  if (s) is.read(f.n, 5);
  return is;
}

int main() {
  std::string input = "   abcde";
  std::istringstream stream(input);
  Foo f;
  stream >> f;
  std::cout.write(f.n, 5);
  std::cout << '\n';
}
```

```exec
abcde
```

### 참고 자료

* `istream::operator>>` : 형식화 된 데이터를 추출한다.