일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- BST
- array
- 자료구조
- 이진 탐색 트리
- Data Structure
- mutable
- 기초
- template
- 전위
- 오버로딩
- 알고리즘
- 숫자
- trading view
- 템플릿 함수화
- 바이낸스
- 비트코인
- 연결 리스트
- SCM
- 트리
- Windows
- Basic
- C++
- Python
- 순회
- 후위
- #선물 #비트코인#알트코인#매매#코인#마진
- 문자열
- linked list
- Tree
- 선물
- Today
- Total
Project Hub
12. 입출력 (istream, ostream) 본문
이전 글
2022.12.21 - [C++/c++ basic] - 11. virtual 함수와 다형성
11. virtual 함수와 다형성
이전 글 2022.12.21 - [C++/c++ basic] - 10. 업 캐스팅 & 다운 캐스팅 10. 업 캐스팅 & 다운 캐스팅 이전 글 2022.12.21 - [C++/c++ basic] - 9. 전위/후위 증감 연산자 오버로딩 & 첨자 연산자 오버로딩 9. 전위/후위
projecthub.tistory.com
C++ 의 입출력 라이브러리는 아래와 같이 구성되어있다.
실제로 입력을 수행하는 클래스는 istream 클래스다.
istream 클래스
operator>> 가 isteam 클래스에 정의되어 있다.
std::cin >> a; 와 같은 형태로 사용할 수 있다.
여러 타입에 대해서도 정의가 되어있고, 아래와 같은 방법을 통해 사용자가 임의로 정의도 가능하다.
istream& operator>>(istream& in, std::string& s)
{
//// 구현
}
operator>> 의 또라른 특징은, 모든 공백문자 (띄어쓰기, 엔터, 탭 등)을 입력시에 무시해버린다.
#include <iostream>
#include <string>
int main()
{
std::string str;
while (true)
{
std::cin >> str;
std::cout << "word : " << str << std::endl;
}
return 0;
}
// 출력
this is a long sentence
word : this
word : is
word : a
word : long
word : sentence
위와 같은 특징은 반드시 주의해야 할 점이 있다.
operator>> 사용 시 주의해야 할 점
아래와 같이 정의된 코드에서, 숫자가 아닌 문자를 사용자가 입력 할 경우, 의도하지 않은 결과가 반환이 된다.
문자를 입력할 경우, t에 0이 담기게 되는 것을 확인했다.
따라서 무한 루프에 빠지게 된다.
#include <iostream>
#include <string>
int main()
{
int t;
while (true)
{
std::cin >> t;
std::cout << "입력 : " << t << std::endl;
if (1 == t) break;
}
return 0;
}
// 문자를 입력할 경우, t에 0이 반환된다.
// 그리고 0이 계속 출력되게 된다. 무한루프에 빠짐
위와 같이 무한루프에 빠지는 원인은 다음과 같다.
ios 클래스에서 스트림의 상태를 관리하는 4개의 플래그가 존재한다.
goodbit: 스트림에 입출력 작업이 가능할 때
badbit: 스트림에 복구 불가능한 오류 발생 시
failbit: 스트림에 복구 가능한 오류 발생 시
eofbit: 입력 작업 시에 EOF 도달 시
문제가 발생한 상황에서 현재 스트림 버퍼에 들어가 있는 문자열은 'c\n' 이다. (문자 'c' 를 입력했다고 가정)
이때의 플래그는 failbit 가 켜지게 되고, 입력 값을 받지 않고 리턴해버린다.
'c\n'가 남아있는 상태에서 리턴을 해버렸기 때문에 버퍼에 남아있는 'c\n'를 다음에 또 읽고, 또 읽게 되는 문제가 발생되어 무한루프에 빠진다.
문제를 해결하기 위해서는 다음과 같이 코드를 수정하면 된다.
#include <iostream>
#include <string>
int main()
{
int t;
while (std::cin >> t)
{
std::cout << "입력 : " << t << std::endl;
if (0 == t) break;
}
return 0;
}
ios 에 정의되어 있는 함수들 중에 다음과 같은 함수가 있다.
operator void*() const;
이 함수는 ios 객체를 void* 로 반환해준다.
이때 NULL 포인터가 아닌 값을 리턴하는 조건은, failbit, badbit 가 off 일 때다.
즉 스트림에 정상적으로 입출력 작업을 수행 할 수 있을 때 NULL이 아닌 값을 반환하게 되는 것이다.
위의 방법으로 문제는 해결 가능하지만, 입력을 계속 진행할 수 없다.
이유는, cin에 fail 비트가 켜진 상태이기 때문이다.
따라서 아래와 같이 goodbit로 초기화를 진행해주고,
ignore 함수를 통해 개행문자가 나올 때 까지 무시할 수 있도록 하면 된다.
#include <iostream>
#include <string>
int main()
{
int t;
while (true)
{
std::cin >> t;
std::cout << "입력 : " << t << std::endl;
if (std::cin.fail())
{
std::cout << "fail" << std::endl;
std::cin.clear(); // goodbit로 초기화
std::cin.ignore(100, '\n'); // 최대 100자 까지 개행 문자가 나올 때 까지 무시.
// 100자 이상이 입력되어 있는 경우, 여러 번 호출 될 수 있다.
}
if (1 == t) break;
}
return 0;
}
'C++ > c++ basic' 카테고리의 다른 글
14. template (0) | 2022.12.21 |
---|---|
13. 파일 입출력 (1) | 2022.12.21 |
11. virtual 함수와 다형성 (0) | 2022.12.21 |
10. 업 캐스팅 & 다운 캐스팅 (0) | 2022.12.21 |
9. 전위/후위 증감 연산자 오버로딩 & 첨자 연산자 오버로딩 (0) | 2022.12.21 |