[C++ 프로그래밍] 입출력 조작자
C++ 기초 프로그래밍: 입출력 조작자
C++ 프로그래밍에서 입출력 조작자는 화면에 출력되는 내용을 형식화하는 데 사용됩니다. 입출력 조작자를 통해 출력 형식을 세밀하게 제어할 수 있으며, 이를 통해 더욱 깔끔하고 가독성 높은 출력을 구현할 수 있습니다. 이번 블로그 글에서는 C++에서 제공하는 다양한 입출력 조작자에 대해 알아보겠습니다.
1. std::endl
std::endl은 줄 바꿈을 수행하고, 출력 버퍼를 플러시합니다. 이는 줄 바꿈 문자인 '\n'을 사용하는 것과 동일하지만, 추가로 버퍼를 플러시하여 출력이 즉시 화면에 나타나도록 합니다.
std::cout << "Hello";
std::cout << "World";
std::cout << std::endl;
std::cout << "Hello" << std::endl;
std::cout << "World" << std::endl;
2. std::flush
std::flush는 출력 버퍼를 플러시합니다. 이는 특정 시점에서 출력 버퍼의 내용을 강제로 출력하는 데 유용합니다.
std::cout << "This is a nice message...." << std::endl << std::flush;
3. std::setw
std::setw는 출력될 항목의 필드 너비를 조정합니다. 이는 정렬된 표를 만들 때 유용합니다.
std::cout << std::setw(10) << "Lastname" << std::setw(10) << "Firstname" << std::setw(5) << "Age" << std::endl;
std::cout << std::setw(10) << "Daniel" << std::setw(10) << "Gray" << std::setw(5) << "25" << std::endl;
4. std::setfill
std::setfill은 std::setw로 지정한 필드의 나머지 부분을 특정 문자로 채웁니다.
std::cout << std::setfill('*');
std::cout << std::setw(10) << "Daniel" << std::setw(10) << "Gray" << std::setw(5) << "25" << std::endl;
5. std::left, std::right, std::internal
- std::left: 왼쪽 정렬
- std::right: 오른쪽 정렬
- std::internal: 부호는 왼쪽 정렬, 데이터는 오른쪽 정렬
std::cout << std::left;
std::cout << std::setw(10) << "Daniel" << std::setw(10) << "Gray" << std::setw(5) << "25" << std::endl;
std::cout << std::right;
std::cout << std::setw(10) << "Daniel" << std::setw(10) << "Gray" << std::setw(5) << "25" << std::endl;
6. std::boolalpha, std::noboolalpha
std::boolalpha는 불리언 값을 true와 false로 출력하며, std::noboolalpha는 1과 0으로 출력합니다.
bool condition {true};
std::cout << std::boolalpha << "condition : " << condition << std::endl; // true
std::cout << std::noboolalpha << "condition : " << condition << std::endl; // 1
7. std::showpos, std::noshowpos
std::showpos는 양수에 대한 + 기호를 표시하며, std::noshowpos는 이를 숨깁니다.
int pos_num {34};
std::cout << std::showpos << "pos_num : " << pos_num << std::endl; // +34
std::cout << std::noshowpos << "pos_num : " << pos_num << std::endl; // 34
8. std::dec, std::hex, std::oct
숫자를 10진수, 16진수, 8진수로 출력합니다.
int pos_int {717171};
std::cout << "pos_int (dec) : " << std::dec << pos_int << std::endl;
std::cout << "pos_int (hex) : " << std::hex << pos_int << std::endl;
std::cout << "pos_int (oct) : " << std::oct << pos_int << std::endl;
9. std::uppercase, std::nouppercase
16진수의 알파벳을 대문자로 출력할지 여부를 설정합니다.
std::cout << std::uppercase << "pos_int (hex) : " << std::hex << pos_int << std::endl; // 0xAFAFAF
std::cout << std::nouppercase << "pos_int (hex) : " << std::hex << pos_int << std::endl; // 0xafafaf
10. std::fixed, std::scientific
부동 소수점 숫자를 고정 소수점 표기법 또는 과학적 표기법으로 출력합니다.
double a {3.1415926535897932384626433832795};
std::cout << std::fixed << "a (fixed) : " << a << std::endl;
std::cout << std::scientific << "a (scientific) : " << a << std::endl;
11. std::setprecision
부동 소수점 값을 출력할 자릿수를 지정합니다.
double a {3.1415926535897932384626433832795};
std::cout << std::setprecision(10) << "a (precision(10)) : " << a << std::endl;
12. std::showpoint, std::noshowpoint
소수점을 강제로 출력할지 여부를 설정합니다.
double f {12.0};
std::cout << std::showpoint << "f : " << f << std::endl; // 12.0
std::cout << std::noshowpoint << "f : " << f << std::endl; // 12
예제 코드
다음 예제 코드는 논리 연산자를 사용하여 불리언 값과 정수 값을 비교하는 방법을 보여줍니다:
#include <iostream>
#include <iomanip>
int main(){
// std::endl : 스트림에 줄 바꿈 문자를 추가
// 이것은 '\n'을 스트림에 추가하는 것과 동일함
std::cout << "Hello";
std::cout << "World";
std::cout << std::endl;
std::cout << "-------------" << std::endl;
std::cout << "Hello" << std::endl;
std::cout << "World" << std::endl;
std::cout << std::endl;
std::cout << "Hello\n";
std::cout << "World\n";
//===================================================================
std::cout << std::endl;
// std::flush : 출력 버퍼를 최종 목적지로 플러시
std::cout << "This is a nice message...." << std::endl << std::flush;
// 이 std::flush 이후에는 이 라인에서 메시지가 스트림으로 전송되었는지 확신할 수 있음
// 이는 일부 응용 프로그램에서 중요할 수 있음
//===================================================================
std::cout << std::endl;
// std::setw() : 출력될 항목의 필드 너비 조정
// setw() 조작자는 출력될 다음 값에만 영향을 미침
std::cout << "Unformatted table : " << std::endl;
std::cout << "Daniel" << " " << "Gray" << " 25" << std::endl;
std::cout << "Stanley" << " " << "Woods" << " 33" << std::endl;
std::cout << "Jordan" << " " << "Parker" << " 45" << std::endl;
std::cout << "Joe" << " " << "Ball" << " 21" << std::endl;
std::cout << "Josh" << " " << "Carr" << " 27" << std::endl;
std::cout << "Izaiah" << " " << "Robinson" << " 29" << std::endl;
std::cout << std::endl;
std::cout << "Formatted table : " << std::endl;
std::cout << std::setw(10) << "Lastname" << std::setw(10) << "Firstname" << std::setw(5) << "Age" << std::endl;
std::cout << std::setw(10) << "Daniel" << std::setw(10) << "Gray" << std::setw(5) << "25" << std::endl;
std::cout << std::setw(10) << "Stanley" << std::setw(10) << "Woods" << std::setw(5) << "33" << std::endl;
std::cout << std::setw(10) << "Jordan" << std::setw(10) << "Parker" << std::setw(5) << "45" << std::endl;
std::cout << std::setw(10) << "Joe" << std::setw(10) << "Ball" << std::setw(5) << "21" << std::endl;
std::cout << std::setw(10) << "Josh" << std::setw(10) << "Carr" << std::setw(5) <<"27" << std::endl;
std::cout << std::setw(10) << "Izaiah" << std::setw(10) << "Robinson" << std::setw(5) << "29" << std::endl;
std::cout << std::endl;
std::cout << "Formatted table with variables: " << std::endl;
int col_width{14};
std::cout << std::setw(col_width) << "Lastname" << std::setw(col_width) << "Firstname" << std::setw(col_width/2) << "Age" << std::endl;
std::cout << std::setw(col_width) << "Daniel" << std::setw(col_width) << "Gray" << std::setw(col_width/2) << "25" << std::endl;
std::cout << std::setw(col_width) << "Stanley" << std::setw(col_width) << "Woods" << std::setw(col_width/2) << "33" << std::endl;
std::cout << std::setw(col_width) << "Jordan" << std::setw(col_width) << "Parker" << std::setw(col_width/2) << "45" << std::endl;
std::cout << std::setw(col_width) << "Joe" << std::setw(col_width) << "Ball" << std::setw(col_width/2) << "21" << std::endl;
std::cout << std::setw(col_width) << "Josh" << std::setw(col_width) << "Carr" << std::setw(col_width/2) <<"27" << std::endl;
std::cout << std::setw(col_width) << "Izaiah" << std::setw(col_width) << "Robinson" << std::setw(col_width/2) << "29" << std::endl;
//===================================================================
std::cout << std::endl;
// 정렬 : 필드 내의 값의 정렬을 조정하는 세 가지 조작자: left, right, internal
// 기본적으로는 오른쪽 정렬
std::cout << std::endl;
std::cout << "Right justified table(default) : " << std::endl;
col_width = 20;
std::cout << std::right;
std::cout << std::setw(col_width) << "Lastname" << std::setw(col_width) << "Firstname" << std::setw(col_width/2) << "Age" << std::endl;
std::cout << std::setw(col_width) << "Daniel" << std::setw(col_width) << "Gray" << std::setw(col_width/2) << "25" << std::endl;
std::cout << std::setw(col_width) << "Stanley" << std::setw(col_width) << "Woods" << std::setw(col_width/2) << "33" << std::endl;
std::cout << std::setw(col_width) << "Jordan" << std::setw(col_width) << "Parker" << std::setw(col_width/2) << "45" << std::endl;
std::cout << std::setw(col_width) << "Joe" << std::setw(col_width) << "Ball" << std::setw(col_width/2) << "21" << std::endl;
std::cout << std::setw(col_width) << "Josh" << std::setw(col_width) << "Carr" << std::setw(col_width/2) <<"27" << std::endl;
std::cout << std::setw(col_width) << "Izaiah" << std::setw(col_width) << "Robinson" << std::setw(col_width/2) << "29" << std::endl;
// 왼쪽 정렬
std::cout << std::endl;
std::cout << "Left justified table : " << std::endl;
col_width = 20;
std::cout << std::left;
std::cout << std::setw(col_width) << "Lastname" << std::setw(col_width) << "Firstname" << std::setw(col_width/2) << "Age" << std::endl;
std::cout << std::setw(col_width) << "Daniel" << std::setw(col_width) << "Gray" << std::setw(col_width/2) << "25" << std::endl;
std::cout << std::setw(col_width) << "Stanley" << std::setw(col_width) << "Woods" << std::setw(col_width/2) << "33" << std::endl;
std::cout << std::setw(col_width) << "Jordan" << std::setw(col_width) << "Parker" << std::setw(col_width/2) << "45" << std::endl;
std::cout << std::setw(col_width) << "Joe" << std::setw(col_width) << "Ball" << std::setw(col_width/2) << "21" << std::endl;
std::cout << std::setw(col_width) << "Josh" << std::setw(col_width) << "Carr" << std::setw(col_width/2) <<"27" << std::endl;
std::cout << std::setw(col_width) << "Izaiah" << std::setw(col_width) << "Robinson" << std::setw(col_width/2) << "29" << std::endl;
// 내부 정렬: 부호는 왼쪽 정렬, 데이터는 오른쪽 정렬
std::cout << std::endl;
std::cout << "Internal justified : " << std::endl;
std::cout << std::right;
std::cout << std::setw(10) << -123.45 << std::endl;
std::cout << std::internal;
std::cout << std::setw(10) << -123.45 << std::endl;
//===================================================================
std::cout << std::endl;
// setfill
std::cout << std::endl;
std::cout << "Table with fill characters : " << std::endl;
col_width = 20;
std::cout << std::left;
std::cout << std::setfill('*'); // 채움 문자 설정
std::cout << std::setw(col_width) << "Lastname" << std::setw(col_width) << "Firstname" << std::setw(col_width/2) << "Age" << std::endl;
std::cout << std::setw(col_width) << "Daniel" << std::setw(col_width) << "Gray" << std::setw(col_width/2) << "25" << std::endl;
std::cout << std::setw(col_width) << "Stanley" << std::setw(col_width) << "Woods" << std::setw(col_width/2) << "33" << std::endl;
std::cout << std::setw(col_width) << "Jordan" << std::setw(col_width) << "Parker" << std::setw(col_width/2) << "45" << std::endl;
std::cout << std::setw(col_width) << "Joe" << std::setw(col_width) << "Ball" << std::setw(col_width/2) << "21" << std::endl;
std::cout << std::setw(col_width) << "Josh" << std::setw(col_width) << "Carr" << std::setw(col_width/2) <<"27" << std::endl;
std::cout << std::setw(col_width) << "Izaiah" << std::setw(col_width) << "Robinson" << std::setw(col_width/2) << "29" << std::endl;
//===================================================================
std::cout << std::endl;
// boolalpha 및 noboolalpha : 불 값의 출력 형식을 제어: 1/0 또는 true/false
bool condition {true};
bool other_condition {false};
std::cout << "condition : " << condition << std::endl;
std::cout << "other_condition : " << other_condition << std::endl;
std::cout << std::endl;
std::cout << std::boolalpha;
std::cout << "condition : " << condition << std::endl;
std::cout << "other_condition : " << other_condition << std::endl;
std::cout << std::endl;
std::cout << std::noboolalpha;
std::cout << "condition : " << condition << std::endl;
std::cout << "other_condition : " << other_condition << std::endl;
//===================================================================
std::cout << std::endl;
// showpos 및 noshowpos : 양수에 대한 + 기호 표시 또는 숨기기
int pos_num {34};
int neg_num {-45};
std::cout << "pos_num : " << pos_num << std::endl;
std::cout << "neg_num : " << neg_num << std::endl;
std::cout << std::endl;
std::cout << std::showpos;
std::cout << "pos_num : " << pos_num << std::endl;
std::cout << "neg_num : " << neg_num << std::endl;
std::cout << std::endl;
std::cout << std::noshowpos;
std::cout << "pos_num : " << pos_num << std::endl;
std::cout << "neg_num : " << neg_num << std::endl;
//===================================================================
std::cout << std::endl;
// 다양한 숫자 시스템 : std::dec, std::hex, std::oct
int pos_int {717171};
int neg_int {-47347};
double double_var {498.32};
std::cout << std::endl;
std::cout << "default base format : " << std::endl;
std::cout << "pos_int : " << pos_int << std::endl;
std::cout << "neg_int : " << neg_int << std::endl;
std::cout << "double_var : " << double_var << std::endl;
std::cout << std::endl;
std::cout << "pos_int in different bases : " << std::endl;
std::cout << "pos_int (dec) : " << std::dec << pos_int << std::endl;
std::cout << "pos_int (hex) : " << std::hex << pos_int << std::endl;
std::cout << "pos_int (oct) : " << std::oct << pos_int << std::endl;
std::cout << std::endl;
std::cout << "neg_int in different bases : " << std::endl;
std::cout << "neg_int (dec) : " << std::dec << neg_int << std::endl;
std::cout << "neg_int (hex) : " << std::hex << neg_int << std::endl;
std::cout << "neg_int (oct) : " << std::oct << neg_int << std::endl;
std::cout << std::endl;
std::cout << "double_var in different bases : " << std::endl;
std::cout << "double_var (dec) : " << std::dec << double_var << std::endl;
std::cout << "double_var (hex) : " << std::hex << double_var << std::endl;
std::cout << "double_var (oct) : " << std::oct << double_var << std::endl;
//===================================================================
std::cout << std::endl;
// uppercase 및 nouppercase
pos_int = 717171;
std::cout << "pos_int (nouppercase : default) : " << std::endl;
std::cout << "pos_int (dec) : " << std::dec << pos_int << std::endl;
std::cout << "pos_int (hex) : " << std::hex << pos_int << std::endl;
std::cout << "pos_int (oct) : " << std::oct << pos_int << std::endl;
std::cout << std::endl;
std::cout << "pos_int (uppercase) : " << std::endl;
std::cout << std::uppercase;
std::cout << "pos_int (dec) : " << std::dec << pos_int << std::endl;
std::cout << "pos_int (hex) : " << std::hex << pos_int << std::endl;
std::cout << "pos_int (oct) : " << std::oct << pos_int << std::endl;
//===================================================================
std::cout << std::endl;
// fixed 및 scientific : 부동 소수점 값에 대해
double a {3.1415926535897932384626433832795};
double b {2006.0};
double c {1.34e-10};
std::cout << std::endl;
std::cout << "double values (default : use scientific where necessary) : " << std::endl;
std::cout << "a : " << a << std::endl;
std::cout << "b : " << b << std::endl;
std::cout << "c : " << c << std::endl;
std::cout << std::endl;
std::cout << "double values (fixed) : " << std::endl;
std::cout << std::fixed;
std::cout << "a : " << a << std::endl;
std::cout << "b : " << b << std::endl;
std::cout << "c : " << c << std::endl;
std::cout << std::endl;
std::cout << "double values (scientific) : " << std::endl;
std::cout << std::scientific;
std::cout << "a : " << a << std::endl;
std::cout << "b : " << b << std::endl;
std::cout << "c : " << c << std::endl;
std::cout << std::endl;
std::cout << "double values (back to defaults) : " << std::endl;
std::cout.unsetf(std::ios::scientific | std::ios::fixed); // 설정 해제
std::cout << "a : " << a << std::endl;
std::cout << "b : " << b << std::endl;
std::cout << "c : " << c << std::endl;
//===================================================================
std::cout << std::endl;
// setprecision() : 부동 소수점 값을 출력할 자릿수 지정. 기본값은 6
a = 3.1415926535897932384626433832795;
std::cout << std::endl;
std::cout << "a (default precision(6)) : " << a << std::endl;
std::cout << std::setprecision(10);
std::cout << "a (precision(10)) : " << a << std::endl;
std::cout << std::setprecision(20);
std::cout << "a (precision(20)) : " << a << std::endl;
// 자릿수가 타입이 지원하는 것보다 크면 쓰레기 값을 출력함
//===================================================================
std::cout << std::endl;
// showpoint 및 noshowpoint : 필요한 경우 뒤에 0을 표시
// 소수점을 강제로 출력
double d {34.1};
double e {101.99};
double f {12.0};
int g {45};
std::cout << std::endl;
std::cout << "noshowpoint (default) : " << std::endl;
std::cout << "d : " << d << std::endl;
std::cout << "e : " << e << std::endl;
std::cout << "f : " << f << std::endl; // 12
std::cout << "g : " << g << std::endl;
std::cout << std::endl;
std::cout << "showpoint: " << std::endl;
std::cout << std::showpoint;
std::cout << "d : " << d << std::endl;
std::cout << "e : " << e << std::endl;
std::cout << "f : " << f << std::endl; // 12.0
std::cout << "g : " << g << std::endl;
return 0;
}
출력 결과
위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다:
HelloWorld
-------------
Hello
World
Hello
World
This is a nice message....
Unformatted table :
Daniel Gray 25
Stanley Woods 33
Jordan Parker 45
Joe Ball 21
Josh Carr 27
Izaiah Robinson 29
Formatted table :
Lastname Firstname Age
Daniel Gray 25
Stanley Woods 33
Jordan Parker 45
Joe Ball 21
Josh Carr 27
Izaiah Robinson 29
Formatted table with variables:
Lastname Firstname Age
Daniel Gray 25
Stanley Woods 33
Jordan Parker 45
Joe Ball 21
Josh Carr 27
Izaiah Robinson 29
Right justified table(default) :
Lastname Firstname Age
Daniel Gray 25
Stanley Woods 33
Jordan Parker 45
Joe Ball 21
Josh Carr 27
Izaiah Robinson 29
Left justified table :
Lastname Firstname Age
Daniel Gray 25
Stanley Woods 33
Jordan Parker 45
Joe Ball 21
Josh Carr 27
Izaiah Robinson 29
Internal justified :
-123.45
- 123.45
Table with fill characters :
Lastname************Firstname***********Age*******
Daniel**************Gray****************25********
Stanley*************Woods***************33********
Jordan**************Parker**************45********
Joe*****************Ball****************21********
Josh****************Carr****************27********
Izaiah**************Robinson************29********
condition : 1
other_condition : 0
condition : true
other_condition : false
condition : 1
other_condition : 0
pos_num : 34
neg_num : -45
pos_num : +34
neg_num : -45
pos_num : 34
neg_num : -45
default base format :
pos_int : 717171
neg_int : -47347
double_var : 498.32
pos_int in different bases :
pos_int (dec) : 717171
pos_int (hex) : af173
pos_int (oct) : 2570563
neg_int in different bases :
neg_int (dec) : -47347
neg_int (hex) : ffff470d
neg_int (oct) : 37777643415
double_var in different bases :
double_var (dec) : 498.32
double_var (hex) : 498.32
double_var (oct) : 498.32
pos_int (nouppercase : default) :
pos_int (dec) : 717171
pos_int (hex) : af173
pos_int (oct) : 2570563
pos_int (uppercase) :
pos_int (dec) : 717171
pos_int (hex) : AF173
pos_int (oct) : 2570563
double values (default : use scientific where necessary) :
a : 3.14159
b : 2006
c : 1.34E-10
double values (fixed) :
a : 3.141593
b : 2006.000000
c : 0.000000
double values (scientific) :
a : 3.141593E+00
b : 2.006000E+03
c : 1.340000E-10
double values (back to defaults) :
a : 3.14159
b : 2006
c : 1.34E-10
a (default precision(6)) : 3.14159
a (precision(10)) : 3.141592654
a (precision(20)) : 3.141592653589793116
noshowpoint (default) :
d : 34.100000000000001421
e : 101.98999999999999488
f : 12
g : 55
showpoint:
d : 34.100000000000001421
e : 101.98999999999999488
f : 12.000000000000000000
g : 55
결론
C++에서 입출력 조작자는 출력 형식을 세밀하게 제어할 수 있는 강력한 도구입니다. 다양한 조작자를 통해 출력 형식을 맞춤 설정하여 가독성을 높이고, 특정 요구사항에 맞는 출력을 구현할 수 있습니다.