Programing/C++

[C++ 프로그래밍] 입출력 조작자

유니얼 2024. 7. 7. 22:31
728x90

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++에서 입출력 조작자는 출력 형식을 세밀하게 제어할 수 있는 강력한 도구입니다. 다양한 조작자를 통해 출력 형식을 맞춤 설정하여 가독성을 높이고, 특정 요구사항에 맞는 출력을 구현할 수 있습니다.

반응형