[목차]
3. 문자열 입력 받기
화면 출력 - cout 과 << 연산자 사용
C++ 에서는 cout과 << 연산자를 이용해 문자열 뿐만 아니라 다양한 데이터를 화면에 출력합니다.
cout 은 스크린 장치와 연결된 C++ 표준 출력 스트림 객체(Standard output stream object) 로, <iostream>의 std namespace 에 속해 있기 때문에 using namespace std; 를 사용하지 않는다면 std:: 를 붙여줘야 합니다.
// cout 과 << 를 이용한 화면 출력
#include <iostream>
double area(int r);
double area(int r){
return 3.14*r*r;
}
int main(){
int n = 3;
char c = '#';
std::cout << c << 5.5 << '-' << n << "hello" << true << std::endl;
std::cout << "n+5 = " << n+5 << '\n';
std::cout << "면적은 " << area(n);
}
<< 연산자는 스트림 삽입 연산자(Stream insertion operator) 라고 불리며 오른쪽 피연산자 데이터를 왼쪽 스트림 객체에 삽입합니다. 원래 << 연산자는 왼쪽 비트 시프트 연산자로 C에서 배웠습니다. C++ 에서도 이 연산자는 똑같은 역할도 수행합니다. 그런데도 cout 과 함께 사용할 때 스트림 삽입 연산자로 동작하는 것은 <iostream> 헤더 파일에 재정의, operator overloading 되어 있기 때문입니다. 연산자 overloading 은 차후에 다시 다뤄보도록 할 건데, 우선은 연산자가 적용되는 상황에 따라 여러 역할을 수행한다. 고 이해하시면 됩니다.
<< 연산자는 문자열뿐 아니라 C++ 에서 제공하는 boo, char, short, int, long, float, double 같은 C++ 기본 데이터 타입도 출력할 수 있습니다. 또한 함수를 그대로 써놔 리턴값을 바로 출력할 수도 있습니다.
#include <iostream>
using namespace std;
namespace Graphic {
int maximum = 100;
}
namespace Math {
int maximum = 65536;
int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
}
int main()
{
cout << "Radius Maximum = " << Graphic::maximum << endl;
cout << "Integer Maximum = " << Math::maximum << endl;
cout << "Interger Add = " << Math::add(2, 4) << endl;
}
위에서 일부러 다양한 예시를 위해 2개의 namespace 를 사용해 cout과 << 를 이용해 출력해보았죠. 클래스 등의 이름(identifier)가 충돌하는 것을 막기 위해, 개발자가 자신만의 고유한 이름 공간을 생성할 수 있도록 C++에서는 namespace 키워드를 제공합니다.
namespace song {
...
}
song :: identifier
namespace 키워드와 중괄호를 통해 namespace 를 생성할 수 있고, 이를 접근할 때는 범위 지정 연산자 :: 를 사용해 접근합니다. :: 는 scope 연산자 라고 주로 부릅니다.
키 입력 받기 - cin 과 >> 연산자 사용
표준 입력 스트림(Standard input stream object)인 cin 과 >> 연산자(스트림 추출 연산자) 로 키를 입력받을 수 있습니다. cout << 와 마찬가지로 모든 기본 타입의 데이터에 대해 >> 연산자로 데이터 입력이 가능합니다. C언어에서는 scanf 같은 함수를 사용할 때 & 연산자를 통해 변수의 주소를 넘겨주거나 하는 복잡한 과정이 있었지만 C++ 에서는 그럴 필요 없이 선언한 변수 그대로를 써주면 입력 받아 바로 저장해줍니다. 훨씬 편리한거죠.
#include <iostream>
using namespace std;
int main()
{
int width;
int height;
cout << "너비와 높이를 입력하세요 : ";
cin >> width >> height;
cout << "넓이 : " << width * height << endl;
}
입력을 통해 유추할 수 있듯 cin 은 여러 개의 >> 연산자를 이용해 여러 값을 입력 받을 수도 있습니다. >> 연산자들은 왼쪽부터 오른쪽으로 순서대로 키보드로부터 입력 받고, "공백"을 기준으로 구분하여 데이터를 받습니다.
그런데 cin 과 >> 연산자는 어떤 것을 기준으로 사용자의 키 입력이 끝났음을 알고 그를 저장할까요? 왜 두번째 데이터는 1이 아니라 10이 정확히 전달되었을까요? 그것은 cin과 >> 연산자는 <Enter> 키를 통해 사용자의 입력이 끝났다고 인식하기 때문입니다.
사용자가 입력한 키들은 곧바로 변수에 저장되는 것이 아니라 cin의 스트림 버퍼에 저장되며, <Enter> 키가 입력되면 비로서 >> 연산자가 cin의 스트림 버퍼에서 키 값을 끌어내어 변수에 저장합니다. <Enter> 키를 누르는 순간 >> 연산자가 동작합니다.
문자열 입력 받기 - cin.getline() 이용 : 배열로 문자열 저장하는 경우
cin 을 이용해 문자열을 입력받는 점은 한계가 있습니다. 왜냐면 "공백"을 기준으로 구분하기 때문에 공백을 만나면 문자열의 입력이 종료된 것으로 인식하기 때문입니다.
#include <iostream>
using namespace std;
int main()
{
char word[100];
for (int i = 0; i < 2; i++) {
cout << "문자열를 입력하세요 : ";
cin >> word;
cout << word << endl;
}
}
따라서 이렇게 배열을 이용해 문자열을 저장하는 경우, cin이 아닌 전체 라인을 읽는 cin 객체의 getline() 멤버 함수를 이용해야 공백이 포함된 문자열을 입력받을 수 있습니다.
cin.getline(char buf[], int size, char delimitChar)
buf : 키보드로부터 읽은 문자열을 저장할 배열
size : buf[] 배열의 크기
delimitChar : 문자열 입력 끝을 지정하는 구분문자
최대 size-1 개의 문자를 입력받거나 delimitChar 로 지정한 구분 문자를 만날 때까지 공백 문자를 포함해 문자열을 입력받는 멤버 함수입니다.
#include <iostream>
using namespace std;
void main()
{
cout << "주소를 입력하세요 >>";
char address[100];
cin.getline(address, 100, '\n');
cout << "주소는 " << address << "입니다" << endl;
}
따라서 위처럼 배열을 사용해 문자열을 저장하는 경우에는 cin 객체의 getline 멤버함수를 사용합니다.
문자열 입력 받기 - getline() 을 이용 : string 객체 사용하는 경우
cin 객체의 getline() 멤버함수를 사용하는 배열에 문자열을 저장하는 방식은 배열의 크기에 의해 문자열의 크기가 제한되는 단점이 있지만, C++ 의 string 객체를 사용하면 문자열의 크기에 제약이 없게 사용할 수 있습니다. string 객체는 마치 동적배열처럼 문자열의 길이가 길어지더라도 그 만큼의 추가적인 메모리를 할당받아 사용하기 때문입니다.
또한 string 클래스를 이용하는 방법은 객체지향적일 뿐 아니라 문자열을 다루기도 쉬우니 C++에서는 문자열을 배열로 다루는 것보다 string 객체로 다루는 것이 바람직합니다. C에서 주구장창 배웠던 strcpy, strcat 등등을 훨씬 쉽게 다룰 수 있습니다. string 객체는 <string> 헤더파일에 선언되어 있기 때문에 이용하기 위해서는 추가적인 include 가 필요합니다.
string 객체를 사용해 문자열을 저장하는 경우, 표준 라이브러리에서 지원하는 getline(istream&, string&) 를 사용할 수 있습니다. getline(cin, 저장할 string) 을 통해 문자열을 입력받는 것이죠. 또한 이렇게 저장한 string 또한 배열처럼 인덱스를 통해 각 문자에 접근할 수 있습니다. 그리고 strcat 을 함수가 아닌 단지 + 연산을 통해서 뒤에 덧붙일 수도 있습니다.
#include <iostream>
#include <string>
using namespace std;
void main() {
string song("Falling in love with you");
string elvis("Elvis Presly");
string singer;
cout << song + "를 부른 가수는" << "(힌트 : 첫 글자는 " << elvis[0] << ")?";
getline(cin, singer);
if (singer == elvis)
cout << "맞았습니다";
else
cout << "틀렸습니다." + elvis + "입니다." << endl;
}
이로부터 혼동을 할 수도 있는데요, + 연산은 오직 string 객체에 대해서만 사용가능합니다.
#include <iostream>
#include <string>
using namespace std;
int main() {
string year = "2023";
cout << year + "년" << endl;
cout << 2022 + "년"; // 틀린 코드. + 연산자는 string 에서만 사용
}
저렇게 t 라는 쌩뚱맞은 값이 나오게 됩니다. 여기까지 C++ 기본 입출력 방법에 대해 알아보았습니다. 감사합니다.
참고 문헌 : 명품 C++ Programming
'C++ > C++ 기초' 카테고리의 다른 글
[C++] 동적 메모리 할당 : new / delete 연산자 (0) | 2023.07.06 |
---|---|
[C++] 문자열 관련 함수 : string 클래스 정리 및 사용법 (0) | 2023.07.05 |
[C++] 템플릿 ( Template ) - 함수 템플릿 / 클래스 템플릿 (0) | 2023.05.05 |
[C++] 생성자와 소멸자 ( Constructor and Destructor ) (0) | 2023.05.05 |
[C++] 클래스 ( Class ) (0) | 2023.05.04 |