티스토리 뷰
주의 사항!
- 이 글은 제가 직접 공부하는 중에 작성되고 있습니다.
- 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
- 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.
다음은 C++에서 "Hello world!"를 출력하는 예제입니다.
#include <iostream>
int main()
{
int i;
double d;
std::cout << "enter num : "; //printf("enter num : ");
std::cin >> i >> d; //scanf("%d%lf", &i, &d);
std::cout << "Hello world!" << std::endl; //printf("Hello world!\n");
std::cout << "Hello " << "world!" << std::endl; //printf("Hello "); printf("world!\n");
std::cout << i << ' ' << 'A' << ' ' << d << std::endl; //printf("%d A %lf\n", i, d);
}
/*
실행 결과
enter num : 20 3.14
Hello world!
Hello world!
20 A 3.14
*/
위 예제를 살펴보면 std::cout과 std::cin, std::endl과 같은 이상한 놈들이 눈에 들어옵니다. 이들이 무엇인지는 처음 보는 것이겠지만 실행 결과를 보아 이들이 입출력에 관여한다는 것을 유추할 수 있을 것입니다. std::cout은 출력, std::cin은 입력을 위해 사용하고, std::endl은 줄 바꿈을 하기 위해 사용하는 모습입니다. 또 std::cout으로 출력할 때는 '<<'로 출력할 데이터와 데이터 사이를 구분하고, std::cin으로 입력받을 때는 '>>'로 입력받을 데이터와 데이터 사이를 구분하는 모습입니다.
코드의 가장 위에는 익숙한 전처리 지시자 #include가 보입니다. 그리고 iostream 헤더 파일을 인클루드 하고 있습니다. C언어에서는 입출력을 위해 stdio.h 헤더 파일을 인클루드 했지만, C++에서는 iostream 헤더 파일을 인클루드 합니다. 근데 해당 파일에 .h 확장자가 붙어 있지 않다는 것을 알 수 있습니다. 왜 그럴까요?
사실 C++의 헤더 파일도 확장자를 가집니다. 그런데 사용자 정의 헤더 파일이 아닌, 라이브러리의 헤더 파일인 경우에 한해서 확장자를 생략하도록 약속되어 있습니다. 그 이유는 C++ 표준과 관련이 있습니다. 과거에는 C++도 C언어와 마찬가지로 헤더 파일에 확장자를 붙여 iostream.h와 같이 사용했습니다. 그런데 새로운 C++ 표준이 도입되면서 새로운 표준 라이브러리가 또 생겨났고, 이 새로운 라이브러리의 헤더 파일을 사용할 때는 확장자를 붙이지 않기로 약속했습니다. 즉, iostream.h는 과거의 표준 라이브러리의 헤더 파일을 의미하고, iostream은 최근 라이브러리의 헤더 파일을 의미하게 됩니다.
std::cout
std::cout 변수는 C언어의 printf() 함수처럼 콘솔 화면에 데이터를 출력시키는 창구 역할을 수행합니다. 아래와 같이 '<<' 연산자를 이용해서 출력할 대상을 연이어 출력할 수 있습니다. 만약 출력 대상의 마지막에 '<<'연산자를 사용하고 이어 std::endl을 출력하면 개행을 하게 됩니다. 즉, std::endl은 '\n'과 같은 의미를 가지고 있습니다.
std::cout << '출력대상1' << '출력대상2' << '출력대상3';
std::cout << '출력대상1' << '출력대상2' << '출력대상3' << std::endl;
'출력 대상'의 위치에는 정수, 실수, 문자, 문자열, 변수 등등 모든 것이 올 수 있습니다. 그리고 C언어와 달리 %d, %lf, %c, %s와 같은 서식 문자로 출력 포맷을 지정하지 않고, 데이터의 성격에 따라 적절한 출력이 이뤄지기 때문에 C언어의 출력방식보다 편리합니다.
std::cin
C++에서 키보드로부터 입력되는 데이터는 std::cin이라고 하는 표준 입력 변수를 통해 전달받습니다.
std::cin 변수를 사용하는 방법은 아래와 같으며 std::cout의 사용법과 매우 유사합니다. 하지만 std::cin 변수는 '<<' 연산자가 아닌 '>>' 연산자를 사용합니다.
std::cin >> '입력대상1' >> '입력대상2' >> '입력대상3';
데이터 입력도 출력과 같이 변수의 입력 포맷을 지정하지 않았습니다. C언어에서는 scanf 함수를 사용해 데이터를 입력받을 때, %d, %lf, %c, %s와 같은 서식 문자를 사용했습니다. 하지만 C++에서는 변수만 알맞게 선언하고 나면 서식 문자는 필요 없이 바로 데이터를 입력받을 수 있습니다.
std::cerr
std::cerr 변수는 에러가 발생하여 데이터를 콘솔 화면에 출력할 때 사용합니다. 사용 예시는 아래와 같습니다.
std::cerr << "에러가 발생하였습니다." << std::endl;
std::cout과 똑같이 데이터를 콘솔 화면에 출력하는 것인데 무엇이 다른지 궁금할 수 있습니다. std::cout 변수는 버퍼를 가지고 있어서 버퍼에 데이터가 쌓이면 출력하지만, std::cerr 변수는 버퍼가 없어서 즉시 화면에 출력한다는 차이점이 있습니다. 때문에 에러 발생 시 에러 메시지를 곧바로 받기 위해 사용합니다.
std::clog
C++에서는 앞에서 언급한 std::cout 변수와 std::cerr 변수 이외에 추가로 std::clog라는 표준 로그 변수를 제공합니다. std::clog 변수는 std::cerr 변수와 동일한 기능을 제공합니다.
std::cout, std::cin, std::endl, std::cerr, std::clog 등은 모두 iostream 헤더 파일에 정의되어 있습니다.
출력 포맷 지정
지금부터는 std::cout 변수를 사용해서 데이터를 콘솔 화면에 출력할 때 상수와 함수를 사용하여 출력하는 데이터의 포맷을 지정하는 몇 가지 방법들을 배워보겠습니다. 아래의 예제를 먼저 보겠습니다.
#include <iostream>
#include <iomanip>
//일자를 'xx/xx/xxxx' 포맷으로 콘솔 화면에 출력하는 함수
void showDate(int m, int d, int y)
{
std::cout << std::setfill('0'); //문자 폭을 채울 수 없다면 0으로 채우라는 의미
std::cout << std::setw(2) << m << '/' //문자 폭을 2로 설정하고 데이터 m 출력
<< std::setw(2) << d << '/'
<< std::setw(4) << y << std::endl;
std::cout << std::endl;
}
int main()
{
//기본적으로 소숫점 이하 6자리를 반올림하여 출력
double f = 3.141592653589793238462643383279502884197169;
std::cout << f << std::endl;
//std::fixed는 실수를 출력할 때 고정 소숫점 자리를 사용하도록 함
//std::setprecision(2)는 소숫점 이하 2자리까지로 설정
double x = 800000.0 / 81.0;
std::cout << std::fixed << std::setprecision(2) << x << std::endl;
x = 2.0 / 3.0;
std::cout << std::fixed << std::setprecision(4) << x << std::endl;
std::cout << std::endl;
showDate(8, 5, 2021); //showDate 함수 호출
//std::showbase는 숫자를 출력할 때 진법을 표시하라는 의미
//std::oct는 8진법으로 숫자 표시
//std::hex는 16진법으로 숫자 표시
unsigned long x1 = 64206;
std::cout << x1 << std::showbase
<< " 8진법은 \"" << std::oct << x1 << "\""
<< " 16진법은 \"" << std::hex << x1 << "\"" << std::endl;
return 0;
}
/*
실행 결과
3.14159
9876.54
0.6667
08/05/2021
64206 8진법은 "0175316" 16진법은 "0xface"
*/
std::setw() 함수, std::setfill() 함수
std::setw() 함수는 데이터의 출력 폭(바이트의 크기)을 입력받은 인수만큼 설정합니다. 예를 들어 std::setw(2)는 데이터의 출력 폭을 2바이트로 설정함을 의미합니다.
std::setfill() 함수는 숫자나 부호가 차지하지 않는 출력 폭의 나머지 영역을 std::setfill() 함수에 제공한 인수로 채워 넣습니다. 만약 std::setfill() 함수를 사용하지 않았다면 디폴트는 공백이 됩니다.
std::fixed 상수, std::setprecision() 함수
실수를 화면에 출력시키는 방법으로 부동 소수점 방식과 고정 소수점 방식이 존재합니다. std::fixed 상수는 실수를 화면에 출력할 때 고정 소수점 방식으로 출력하라는 의미로 사용합니다.
std::setprecision() 함수는 출력할 실수의 정밀도를 전달받은 인수만큼 설정합니다. 위의 예제에서는 2를 인수로 전달받아 소수점 이하 2자리까지로 설정하게 되었습니다.
std::showbase, std::dec, std::oct, std::hex
std::showbase는 10진법이 아닌 8진법이나 16진법을 콘솔 화면이나 파일로 출력할 때 숫자 앞에 '0'이나 '0x'와 같이 진법을 표시하라는 의미로 사용됩니다. 그리고 std::dec은 10진법, std::oct는 8진법, std::hex는 16진법으로 출력하라는 의미이며, 이들을 사용하지 않을 때 디폴트는 10진법이 됩니다.
std::left, std::right, std::internal
std::left는 출력할 숫자나 문자를 왼쪽으로 정렬합니다. std::setw() 함수와 함께 사용됩니다. std::right은 오른쪽 정렬, std::internal은 내부 폭 전체에 걸쳐서 정렬하도록 합니다. 아래는 예제입니다.
#include <iostream>
#include <iomanip>
int main()
{
std::cout << "Left fill : \n" << std::left
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::showbase << std::hex << 42 << std::endl;
std::cout << std::endl;
std::cout << "Internal fill : \n" << std::internal
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::showbase << std::hex << 42 << std::endl;
std::cout << std::endl;
std::cout << "Right fill : \n" << std::right
<< std::setw(12) << -1.23 << '\n'
<< std::setw(12) << std::showbase << std::hex << 42 << std::endl;
std::cout << std::endl;
return 0;
}
/*
실행 결과
Left fill :
-1.23
0x2a
Internal fill :
- 1.23
0x 2a
Right fill :
-1.23
0x2a
*/
std::scientific, std::hexfloat, std::defaultfloat
std::scientific은 지수를 이용한 실수를 부동 소수점 방식으로 출력하도록 합니다. std::hexfloat은 실수를 16진법의 부동 소수점 방식으로 출력합니다. std:defaultfloat은 실수를 디폴트 방식으로 출력합니다. 아래는 예제입니다.
#include <iostream>
#include <iomanip>
int main()
{
double a = 3.1415926535;
double b = 2006.0;
double c = 1.0e-10;
std::cout << "scientific : \n" << std::scientific
<< a << '\n' << b << '\n' << c << '\n' << std::endl;
std::cout << "hexfloat : \n" << std::hexfloat
<< a << '\n' << b << '\n' << c << '\n' << std::endl;
std::cout << "defaultfloat : \n" << std::defaultfloat
<< a << '\n' << b << '\n' << c << '\n' << std::endl;
return 0;
}
/*
실행 결과
scientific :
3.141593e+00
2.006000e+03
1.000000e-10
hexfloat :
0x1.921fb54411744p+1
0x1.f580000000000p+10
0x1.b7cdfd9d7bdbbp-34
defaultfloat :
3.14159
2006
1e-10
*/
'공부 일지 > CPP 공부 일지' 카테고리의 다른 글
C++ | 새로운 자료형 bool (0) | 2021.07.31 |
---|---|
C++ | 네임스페이스(namespace) (0) | 2021.07.31 |
C++ | 인라인(inline) 함수 (0) | 2021.07.31 |
C++ | 매개변수의 디폴트 값 (0) | 2021.07.31 |
C++ | 함수 오버로딩 (0) | 2021.07.31 |