1. 출력
1.1. class 분석
class 관련 자료 확인 검색 시 다음의 자료를 볼 수 있었다. 현재 C++20 버전의 구조를 보기 편하게 정리된 자료입니다.
(참고: https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp10_IO.html)
1.1.1. Iosb
ios_base의 base class
1.1.2. ios_base
ios를 위한 base class
- 멤버변수
1.1.3. _Locbase
locale클래스 의 base class
1.1.4. locale
문자의 출력 방식 등 나라에 따라 달라지는 설정을 저장하기 위한 class
- 멤버변수
- 내부 추가 class
(1) id: 멤버 클래스는 locale의 패싯을 조회하기 위한 인덱스로 사용되는 고유한 패싯 ID 제공을 위한 클래스
(identifier stamp, unique for each distinct kind of facet)
(2) _Locimp: 참조 카운트 된 locale의 실제 구현이 이뤄지는 클래스 (reference-counted actual implementation of a locale)
(3) facet: locale이 구현하는 패싯에 대한 포인터를 단일 인덱스 컨테이너에 저장할 수 있도록 지원하는 클래스
내부에 facet 관련 구조체로 자신을 가리키는 포인터와 참조 카운터를 갖고 있는다.
(4) _Ptr: 로케일 구현 객체에 대한 포인터
1.1.3. basic_ios
basic_istream/basic_ostream을 위한 base class
- 멤버 변수: basic_ios는 ostream과 stream buffer를 멤버변수로 갖고 있는다.
1.1.4. ostream
- 멤버변수 정리
(1) ios_base
(2) basic_ios
(3) ostream
class 내 멤버변수 미포함
1.2. Output formatting
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
// 1. 상태 저장 및 초기화
std::ios state(NULL);
state.copyfmt(std::cout);
std::cout.copyfmt(std::ios(NULL));
// 2. showpos/noshowpos
// int
cout << showpos << 12 << endl; // +12
cout << noshowpos << 12 << endl; // 12
// float
cout << showpos << 12.3 << endl; // +12.3
cout << noshowpos << 12.3 << endl; // 12.3
// string
cout << showpos << "12" << endl; // 12
cout << noshowpos << "12" << endl; // 12
// 3. dec/hex/oct
std::cout.copyfmt(std::ios(NULL));
// int
cout << hex << 12 << endl; // c (c = 12)
cout << dec << 12 << endl; // 12
cout << oct << 12 << endl; // 14 (8 + 4 = 12)
// float
cout << hexfloat << 12.3 << endl; // 0x1.899999999999ap+3
// string
cout << hex << "12" << endl; // 12
cout << dec << "12" << endl; // 12
cout << oct << "12" << endl; // 12
// 4. uppercase/nouppercase
std::cout.copyfmt(std::ios(NULL));
// int
cout << hex << uppercase << 12 << endl; // C
cout << hex << nouppercase << 12 << endl; // c
// float
cout << hexfloat << uppercase << 12.3 << endl; // 0X1.899999999999AP+3
cout << hexfloat << nouppercase << 12.3 << endl; // 0x1.899999999999ap+3
// string
cout << uppercase << "abcd" << endl; // abcd
cout << nouppercase << "abcd" << endl; // abcd
// 5. showbase/noshowbase
std::cout.copyfmt(std::ios(NULL));
// int (hex)
cout << hex << showbase << 12 << endl; // 0xb
cout << hex << noshowbase << 12 << endl; // b
// int (dec)
cout << dec << showbase << 12 << endl; // 12
cout << dec << noshowbase << 12 << endl; // 12
// int (oct)
cout << oct << showbase << 12 << endl; // 014
cout << oct << noshowbase << 12 << endl; // 14
// 6. setw()
std::cout.copyfmt(std::ios(NULL));
// int
cout << setw(4) << 12 << endl; // __12
cout << setw(4) << 12345 << endl; // 12345
// float
cout << setw(4) << 12.345 << endl; // 12.345
cout << setw(4) << 12.3 << endl; // 12.3
// string
cout << setw(4) << "12" << endl; // __12
cout << setw(4) << "12345" << endl; // 12345
// 7. setfill()
std::cout.copyfmt(std::ios(NULL));
// int
cout << setw(4) << setfill('*') << 12 << endl; // **12
cout << setw(4) << setfill('*') << 12345 << endl; // 12345
cout << setw(4) << 12 << endl; // __12
// float
cout << setw(4) << setfill('*') << 12.345 << endl; // 12.345
cout << setw(4) << setfill('*') << 12.3 << endl; // 12.3
// string
cout << setw(4) << setfill('*') << "12" << endl; // **12
cout << setw(4) << setfill('*') << "12345" << endl; // 12345
// 8. left/right/internal
std::cout.copyfmt(std::ios(NULL));
// int
cout << hex << showbase << showpos << left;
cout << setw(5) << 12 << endl; // 0xc
cout << setw(5) << 12345 << endl; // 0x3039
cout << dec;
cout << setw(5) << 12 << endl; // +12
cout << setw(5) << 12345 << endl; // +12345
cout << hex << right;
cout << setw(5) << 12 << endl; // __0xc
cout << setw(5) << 12345 << endl; // 0x3039
cout << dec;
cout << setw(5) << 12 << endl; // __+12
cout << setw(5) << 12345 << endl; // +12345
cout << hex << internal;
cout << setw(5) << 12 << endl; // 0x__c
cout << setw(5) << 12345 << endl; // 0x3039
cout << dec;
cout << setw(5) << 12 << endl; // +__12
cout << setw(5) << 12345 << endl; // +12345
// float
cout << showbase << showpos << left;
cout << setw(6) << 1.2 << endl; // +1.2
cout << setw(6) << 1. << endl; // +1
cout << setw(6) << 1.2345 << endl; // +1.2345
cout << right;
cout << setw(6) << 1.2 << endl; // __+1.2
cout << setw(6) << 1. << endl; // ____+1
cout << setw(6) << 1.2345 << endl; // +1.2345
cout << internal;
cout << setw(6) << 1.2 << endl; // +__1.2
cout << setw(6) << 1. << endl; // +____1
cout << setw(6) << 1.2345 << endl; // +1.2345
// string
cout << left;
cout << setw(5) << "12" << endl; // 12
cout << setw(5) << "123456" << endl; // 123456
cout << right;
cout << setw(5) << "12" << endl; // ___12
cout << setw(5) << "123456" << endl; // 123456
cout << internal;
cout << setw(5) << "12" << endl; // ___12
cout << setw(5) << "123456" << endl; // 123456
// 9. setprecision
std::cout.copyfmt(std::ios(NULL));
// float
cout << setprecision(6) << 12.345678 << endl; // 12.3457
cout << setprecision(6) << 12.3456 << endl; // 12.3456
cout << setprecision(6) << 12.345 << endl; // 12.345
// 10. showpoint/noshowpoint
std::cout.copyfmt(std::ios(NULL));
// int
cout << showpoint << 123 << endl; // 123
cout << noshowpoint << 123 << endl; // 123
// float
cout << showpoint << 12.3 << endl; // 12.3000
cout << noshowpoint << 12.3 << endl; // 12.3
// string
cout << showpoint << "123" << endl; // 123
cout << noshowpoint << "123" << endl; // 123
// 11. scienantific/fixed
std::cout.copyfmt(std::ios(NULL));
// float
cout << 12.34 << endl; // 12.34
cout << scientific << 12.34 << endl; // 1.234000e+01
cout << fixed << 12.34 << endl; // 12.340000
cout << fixed << setprecision(4) << 12.34 << endl; // 12.3400
// 12. boolalpha/noboolalpha
std::cout.copyfmt(std::ios(NULL));
// bool
cout << boolalpha << true << endl; // true
cout << noboolalpha << true << endl; // 1
cout << boolalpha << false << endl; // false
cout << noboolalpha << false << endl; // 0
std::cout.copyfmt(std::ios(NULL));
cout.setf(ios_base::hex);
cout << 12 << endl; // 12
cout.setf(ios_base::hex, ios_base::basefield);
cout << 12 << endl; // c
return 0;
}
1.2.1. manipulator
'ostream'의 부모클래스인 ' ios_base' 내 fmtflags를 설정하여 출력 방식을 제어한다.
이때, fmtflags는 int형으로 bitmask 방식으로 동작이 이뤄진다. (mask에 대한 동작 방식은 '_Iosb' class 내에 정의되어있다.)
1.2.1.1. 상태 저장 및 초기화
상태 저장: ios_base에 설정된 옵션을 가져온다. (참고: https://cplusplus.com/reference/ios/ios/copyfmt/)
초기화: copyfmt을 응용하여 초기화 ios 값 복사를 통해 초기화를 적용한다.
// 상태 저장
std::ios state(NULL);
state.copyfmt(std::cout);
// 초기화
std::cout.copyfmt(std::ios(NULL));
1.2.1.2. showpos/noshowpos
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (showpos = 0x0020)
showpos: 양수에 부호를 표시한다.
noshowpos: 양수에 부호를 표시하지 않는다.
// int
cout << showpos << 12 << endl; // +12
cout << noshowpos << 12 << endl; // 12
// float
cout << showpos << 12.3 << endl; // +12.3
cout << noshowpos << 12.3 << endl; // 12.3
// string
cout << showpos << "12" << endl; // 12
cout << noshowpos << "12" << endl; // 12
1.2.1.3. dec/hex/oct
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (dec/oct/hex = 0x0200/0x0400/0x0800)
dec: 10진수 표기법을 사용한다.
hex: 16진수 표기법을 사용한다.
oct: 8진수 표기법을 사용한다.
// int
cout << hex << 12 << endl; // c (c = 12)
cout << dec << 12 << endl; // 12
cout << oct << 12 << endl; // 14 (8 + 4 = 12)
// float
cout << hexfloat << 12.3 << endl; // 0x1.899999999999ap+3
// string
cout << hex << "12" << endl; // 12
cout << dec << "12" << endl; // 12
cout << oct << "12" << endl; // 12
basefield: setf 동작 시 bitmask를 위한 구간 지정 (basefield = 0x0x0E00 //dec | oct | hex)
1.2.1.4. uppercase/nouppercase
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (uppercase = 0x0004)
uppercase: 16진수 출력 시 대문자로 출력한다.
nouppercase: 16진수 출력 시 소문자로 출력한다.
// int
cout << hex << uppercase << 12 << endl; // C
cout << hex << nouppercase << 12 << endl; // c
// float
cout << hexfloat << uppercase << 12.3 << endl; // 0X1.899999999999AP+3
cout << hexfloat << nouppercase << 12.3 << endl; // 0x1.899999999999ap+3
// string
cout << uppercase << "abcd" << endl; // abcd
cout << nouppercase << "abcd" << endl; // abcd
1.2.1.5. showbase/noshowbase
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (showbase = 0x0008)
showbase: 16진수, 8진수 출력 시 포멧에 따른 접두사를 붙여준다.
1) 16진수 출력: '0x' 추가
2) 8진수 출력: '0' 추가
noshowbase: 접두사를 붙이지 않는다.
// int (hex)
cout << hex << showbase << 12 << endl; // 0xb
cout << hex << noshowbase << 12 << endl; // b
// int (dec)
cout << dec << showbase << 12 << endl; // 12
cout << dec << noshowbase << 12 << endl; // 12
// int (oct)
cout << oct << showbase << 12 << endl; // 014
cout << oct << noshowbase << 12 << endl; // 14
1.2.1.6. setw()
setw: 'ios_base' 내 멤버변수 중 '_Wide' 변경 (default: 0)을 통해 출력할 문자의 길이 제어
특이사항: 매 출력 시 설정 필요
// int
cout << setw(4) << 12 << endl; // __12
cout << setw(4) << 12345 << endl; // 12345
// float
cout << setw(4) << 12.345 << endl; // 12.345
cout << setw(4) << 12.3 << endl; // 12.3
// string
cout << setw(4) << "12" << endl; // __12
cout << setw(4) << "12345" << endl; // 12345
1.2.1.7. setfill()
setfill: 'basic_ios' 내 멤버변수 중 '_Fillch' 변경 (default: 32, ' ')을 통해 공백을 채울 문자 결정
// int
cout << setw(4) << setfill('*') << 12 << endl; // **12
cout << setw(4) << setfill('*') << 12345 << endl; // 12345
// float
cout << setw(4) << setfill('*') << 12.345 << endl; // 12.345
cout << setw(4) << setfill('*') << 12.3 << endl; // 12.3
// string
cout << setw(4) << setfill('*') << "12" << endl; // **12
cout << setw(4) << setfill('*') << "12345" << endl; // 12345
1.2.1.8. left/right/internal
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (left/right/internal = 0x0040/0x0080/0x0100)
left: 좌측 정렬
right: 우측 정렬
internal: 접두사-좌측 정렬 / 데이터-우측 정렬
// int
cout << hex << showbase << showpos << left;
cout << setw(5) << 12 << endl; // 0xc
cout << setw(5) << 12345 << endl; // 0x3039
cout << dec;
cout << setw(5) << 12 << endl; // +12
cout << setw(5) << 12345 << endl; // +12345
cout << hex << right;
cout << setw(5) << 12 << endl; // __0xc
cout << setw(5) << 12345 << endl; // 0x3039
cout << dec;
cout << setw(5) << 12 << endl; // __+12
cout << setw(5) << 12345 << endl; // +12345
cout << hex << internal;
cout << setw(5) << 12 << endl; // 0x__c
cout << setw(5) << 12345 << endl; // 0x3039
cout << dec;
cout << setw(5) << 12 << endl; // +__12
cout << setw(5) << 12345 << endl; // +12345
// float
cout << showbase << showpos << left;
cout << setw(6) << 1.2 << endl; // +1.2
cout << setw(6) << 1. << endl; // +1
cout << setw(6) << 1.2345 << endl; // +1.2345
cout << right;
cout << setw(6) << 1.2 << endl; // __+1.2
cout << setw(6) << 1. << endl; // ____+1
cout << setw(6) << 1.2345 << endl; // +1.2345
cout << internal;
cout << setw(6) << 1.2 << endl; // +__1.2
cout << setw(6) << 1. << endl; // +____1
cout << setw(6) << 1.2345 << endl; // +1.2345
// string
cout << left;
cout << setw(5) << "12" << endl; // 12
cout << setw(5) << "123456" << endl; // 123456
cout << right;
cout << setw(5) << "12" << endl; // ___12
cout << setw(5) << "123456" << endl; // 123456
cout << internal;
cout << setw(5) << "12" << endl; // ___12
cout << setw(5) << "123456" << endl; // 123456
adjustfield: setf 동작 시 bitmask를 위한 구간 지정 (basefield = 0x0x01C0 //left | right | internal)
1.2.1.9. setprecision()
setprecision: 'ios_base' 내 멤버변수 중 '_Prec' 변경 (default: 6)을 통해 출력할 유효 자릿수 결정
// float
cout << setprecision(6) << 12.345678 << endl; // 12.3457
cout << setprecision(6) << 12.3456 << endl; // 12.3456
cout << setprecision(6) << 12.345 << endl; // 12.345
1.2.1.10. showpoint/noshowpoint
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (showpoint = 0x0010)
showpoint: 소수 부분이 0인 경우에도 표현
noshowpoint: 소수 부분이 0인 경우 생략
// int
cout << showpoint << 123 << endl; // 123
cout << noshowpoint << 123 << endl; // 123
// float
cout << showpoint << 12.3 << endl; // 12.3000
cout << noshowpoint << 12.3 << endl; // 12.3
// string
cout << showpoint << "123" << endl; // 123
cout << noshowpoint << "123" << endl; // 123
1.2.1.11. scienantific/fixed
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (scientific/fixed = 0x2000/0x1000)
scientific: 과학적 표기법을 활용하여 부동 소수점 표현
fixed: 기본 표현을 활용하여 부동 소수점 표현
// float
cout << 12.34 << endl; // 12.34
cout << scientific << 12.34 << endl; // 1.234000e+01
cout << fixed << 12.34 << endl; // 12.340000
cout << fixed << setprecision(4) << 12.34 << endl; // 12.3400
floatfield: setf 동작 시 bitmask를 위한 구간 지정 (floatfield = 0x0x3000 // scientific | fixed)
1.2.1.12. boolalpha/noboolalpha
'ios_base' 내 멤버변수 중 '_Fmtfl'에 flag 정보 추가 (boolalpha = 0x4000)
boolalpha: bool 값을 문자로 표시 (false/true)
noboolalpha: bool 값을 정수로 표시 (0/1)
// bool
cout << boolalpha << true << endl; // true
cout << noboolalpha << true << endl; // 1
cout << boolalpha << false << endl; // false
cout << noboolalpha << false << endl; // 0
1.2.2. setf(), unsetf()
fmtflag를 직접 제어하는 함수
cout.setf(ios_base::hex);
cout << 12 << endl; // 12
cout.setf(ios_base::hex, ios_base::basefield);
cout << 12 << endl; // c
(1) setf(flag) / unsetf(flag)
(2) setf(flag, flag)
- dec/oct/hex basefield
- fixed/scientific floatfield
- left/right/internal adjustfield
1.3. 출력 동작 분석
실제 응용은 아래의 구문을 진행하며, 출력이 이뤄진다.
1.3.1. operator<<(int _Val) (in 'basic_ostream' class)
int형 출력 시 facet을 활용하고, fmtflag 중 basefield를 사용한다.
1.3.1.1. rdbuf() (in 'basic_ios' class)
stream buffer의 포인터 위치를 반환함.
1.3.1.2. fill() (in 'basic_ios' class)
빈 공간을 채울 character를 반환함. (이때, _Elem은 char가 활용된다. 예외적인 상황은 추후 고민해보자.)
1.3.1.3. put (in 'num_put' class)
1.3.1.3.1. do_put (in 'num_put' class)
1.3.1.3.1.1. _Ifmt (in 'num_put' class)
int형 출력을 위한 format
+) _Ffmt (in 'num_put' class)
floating-point 출력을 위한 포멧
1.3.1.3.1.2. sprintf_s (global, in 'stdio.h' class)
_Buffer에 _Format에 따라 변경된 문자열을 저장
1.3.1.3.1.3. _Iput (in 'num_put' class)
Integer 형식의 출력을 위한 구현부
+) Fput (in 'num_put' class)
Floating-point 형식의 출력을 위한 구현부
1.3.1.3.1.3.1. getloc() (in 'ios_base' class)
locale을 활용
1.3.1.3.1.3.2. widen() (in 'ctype' class)
char 형식의 문자를 locale에서 사용하는 ctype 형태의 문자로 변환
1.3.1.3.1.3.3. _Put (in 'num_put' class)
[_Ptr, _Prt + _Count] 범위의 값을 _Dest 메모리로 복사
1.3.1.3.1.3.4. _Rep (in 'num_put' class)
'_Count' 횟수만큼 '_Ch' 데이터를 _Dest 메모리로 복사
1.3.2. endl (in 'basic_ostream' class)
1.3.2.1. put (in 'basic_ostream' class)
1.3.2.2. flush (in 'basic_ostream' class)
1.3.2.2.1. rdbuf (in 'basic_ios' class)
stream buffer 포인터 반환
1.3.2.2.2. pubsync, sync (in 'basic_streambuf' class)
(참고: https://learn.microsoft.com/ko-kr/cpp/standard-library/basic-streambuf-class?view=msvc-170)
외부 스트림과 동기화
'--------private--------- > |c++| 유용한 정보' 카테고리의 다른 글
[c++]memset 함수를 사용하는법(배열을 내가 원하는 수로 초기화하는 방법) (0) | 2019.03.30 |
---|---|
웹 컴파일러 (0) | 2019.02.09 |