C++/카루의 C++ 강좌

[카루의 C++ 강좌] 1-5. 입력받기 - std::cin과 std::scanf()

카루-R 2020. 3. 21. 00:31
반응형

이제는 사용자에게서 직접 값을 입력받아보겠습니다. 소통하는 프로그램의 시작입니다.

C++에서 입력은 std::cin을 통해서 받으며, std::cout와는 방향이 반대인 >> 를 통해 값을 입력받습니다.

#include <iostream>

int main()
{
    std::string name, phone;
    int age;

    std::cout << "당신의 이름을 입력하세요: ";
    std::cin >> name;

    std::cout << "당신의 나이를 입력하세요: ";
    std::cin >> age;

    std::cout << "당신의 전화번호를 입력하세요: ";
    std::cin >> phone;

    std::cout << std::endl << "안녕하세요, " << name << "님." << std::endl;
    std::cout << "당신의 나이는 " << age << "살이고 "
        << "전화번호는 " << phone << "이군요!" << std::endl;
       return 0;
}
당신의 이름을 입력하세요: 카루
당신의 나이를 입력하세요: 346
당신의 전화번호를 입력하세요: 0100-987-54321

안녕하세요, 카루님.
당신의 나이는 346살이고 전화번호는 0100-987-54321이군요!

값을 입력할 때는 원하는 값을 입력하고 엔터키를 눌러줘야 입력이 완료됩니다. 저 프로그램을 만든다고 저한테 뭐 개인정보가 넘어오거나 그러지는 않으니 안심하세요.

한 줄 씩 살펴보겠습니다.

std::string name, phone;

std::string 타입의 인스턴스(=변수) name, phone을 선언했습니다. std::string은 문자열을 저장하는 타입이며 (클래스입니다. '7-1 클래스와 구조체'에서 다룹니다) 이름에서 유추할 수 있듯 이름과 전화번호를 저장하는 인스턴스(=변수)입니다.

std::cout << "당신의 이름을 입력하세요: ";
std::cin >> name;

이름을 입력하라는 문구를 출력한 후, std::cin을 통해 name 변수에 입력을 받습니다. std::cout 처럼 꺾쇠 괄호를 사용하며, 형식에 관계 없이 모든 타입을 입력받을 수 있습니다.

std::cout << std::endl << "안녕하세요, " << name << "님." << std::endl;
std::cout << "당신의 나이는 " << age << "살이고 "
    << "전화번호는 " << phone << "이군요!" << std::endl;

입력 받은 변수를 바탕으로 퍼즐 조립하듯 문자열을 출력합니다. 이 부분은 이제 익숙하시죠?

그럼 이제 입력받은 값을 바탕으로 평균을 구해보는 프로그램을 만들어보겠습니다.

#include <iostream>

int main()
{
    int num1, num2, num3, num4, num5;

    std::cout << "5개의 숫자를 입력하세요: ";
    std::cin >> num1;
    std::cin >> num2;
    std::cin >> num3;
    std::cin >> num4;
    std::cin >> num5;

    std::cout << num1 << ", " << num2 << ", "
        << num3 << ", " << num4 << ", " << num5
        << "의 평균: " << (num1 + num2 + num3 + num4 + num5) / 5 << std::endl;
       return 0;
}
5개의 숫자를 입력하세요: 34 65 94 32 76
34, 65, 94, 32, 76의 평균: 60

참고로, std::cin은 std::cout처럼 여러 값을 한번에 다룰 수 있습니다. 따라서 위 코드에서 입력받는 부분을 아래처럼 줄일 수 있습니다. (8-12 줄)

std::cin >> num1 >> num2 >> num3 >> num4 >> num5;

여러 값을 한 번에 입력 받을 때는 공백으로 각 입력을 구분해주면 됩니다. 혹은 하나 입력하고 엔터를 치는 식으로 입력해도 됩니다.

그리고 입력받은 값을 출력한 후, 그것의 평균을 계산해서 출력하게 됩니다. 위의 std::cout는 아래처럼 std::printf()로 바꿀 수 있습니다.

std::printf("%d, %d, %d, %d, %d의 평균: %d\n", num1, num2, num3, num4, num5,
      (num1 + num2 + num3 + num4 + num5) / 5);

이럴 때는 std::printf()가 더 편해보이기도 하지만 std::cout에서 std::format을 쓸 수 있다는 걸 생각하면 꼭 그렇지도 않습니다.

std::cout << std::format("{}, {}, {}, {}, {}의 평균: {}", num1, num2, num3, num4, num5,
      (num1 + num2 + num3 + num4 + num5) / 5) << std::endl;

참고로 이 코드는 C++20이상에서만 동작하는데, 2020년 3월 현재 저걸 지원하는 컴파일러가 없습니다(...)

이 강좌를 여러분들이 보실 때 쯤이면 아마 사용 가능할겁니다.

당연하지만 실수도 입력 가능합니다.

#include <iostream>
#include <cmath> // std::abs()를 사용하기 위해 필요합니다.

int main()
{
    double db1, db2;

    std::cout << "2개의 실수를 입력하세요: ";
    std::cin >> db1 >> db2;

    std::cout << "두 실수의 합: " << db1 + db2 << std::endl
        << "두 실수의 차: " << std::abs(db1 - db2) << std::endl
        << "두 실수의 곱: " << db1 * db2 << std::endl;
    return 0;
}
2개의 실수를 입력하세요: 1.6483 35.4635
두 실수의 합: 37.1118
두 실수의 차: 33.8152
두 실수의 곱: 58.4545

#include가 추가되었습니다. include에 대해서는 다음 강좌에 더 자세하게 소개합니다만, 일단 저 문장을 통해 std::abs() 함수를 사용할 수 있다고만 알아두시면 되겠습니다.

실수 두 개를 입력받아서 그것의 합, 차, 곱을 출력하는 프로그램입니다. 차는 절댓값을 구해야 하는데, 이때 std::abs() 함수가 절댓값을 구해서 반환합니다. std::abs 함수의 원형은

double abs(double _Arg); // 외 6개 오버로드

입니다. double값을 매개변수로 받고, double값을 반환합니다.

이 외에 입력 형식을 조절할 수 있습니다!

"[C++ 심화] 4. std::cin의 입력 형식 지정"을 참고해 주세요.

std::scanf()

std::cin이 std::cout와 짝을 이룬다면 std::scanf()는 std::printf() 함수와 짝을 이룹니다. 그런데 이 함수는 사용법이 조금 특이합니다.

int scanf( const char * _Format [, _Argument]... );

이 함수도 서식 문자를 사용합니다. 하지만 사용법은 약간 다릅니다.

%c

char

문자

%d

short, int

부호 있는 10진수

%u

unsigned int

%i

int

부호 있는 8, 10, 16진수

%o, %x, %X

각각 8진수, 16진수(소문자),

16진수(대문자)

%e, %E, %f, %g, %G

float

실수

%lf

double

double db1, db2;

std::printf("2개의 실수를 입력하세요: ");
std::scanf("%lf %lf", &db1, &db2);

std::printf("두 실수의 합: %f\n", db1 + db2);
std::printf("두 실수의 차: %f\n", std::abs(db1 - db2));
std::printf("두 실수의 곱: %f\n", db1 * db2);

아까 그 소스코드를 std::scanf()를 이용하여 다시 작성했습니다. 보시다시피

std::scanf("%lf %lf", &db1, &db2);

형식문자로 %lf를 사용하고, 두 개 이상의 입력을 받을 경우 띄어씁니다. 쉼표를 쓰면 에러가 납니다! 그리고 입력받는 변수의 앞엔 &을 붙여줘야 합니다.

사실 std::scanf()도 C언어에서 내려온 함수라 크게 신경쓰지 않으셔도 됩니다. 아니, 잊는 게 오히려 좋으실 수도 있어요. std::printf()는 std::cout 보다 편할 때가 가끔 있지만, std::scnaf()에 비해선 std::cin이 압도적으로 편리하기 때문입니다.

1-5. 도전 과제

  1. 자신의 가족의 나이를 입력받아 그 합을 출력해 보세요.
  2. 올해 연도와 사용자의 나이, 정수형 변수 n을 입력받고, n년 후의 연도와 사용자의 나이를 출력하는 프로그램을 작성해 보세요.

수고하셨습니다. 이제 기본적인 입출력은 끝났습니다.
다음시간에는 전처리기, #include와 #define을 배우고, 2단원으로 넘어가겠습니다.

참고: 본 강좌의 연계 심화 강좌는
"[C++ 심화] 4. std::cin의 입력 형식 지정"입니다.

반응형