각 테스트 케이스는 한 라인으로 주어진다.
<iostream>의 cin 입력은 한 라인 전체를 입력받지 못한다.
각 테스트 케이스에서 주어지는 수학식의 양식은 숫자 연산자 연산자 ... 형태이다.
연산자의 숫자가 고정되어있다면
double num;
char op1, op2;
cin >> op1 >> op2;
이런 식으로 입력받을 수 있었겠지만 이 문제에서는 연산자가 최대 3개로 유동적이다.
따라서 한 라인 전체를 스트링으로 불러오는 것이 낫다.
문법
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
입력 스트림 is 에서 추출한 문자들을 스트링 변수 str에 저장한다.
구분자 delim 인자가 있다면 구분자 전까지 저장되며 구분자는 버려진다.
구분자가 없다면 파일의 끝에 도달하거나 개행문자 \n이 올 때까지 추출한다.
예시 1
#include <iostream>
#include <string>
int main ()
{
std::string name;
std::getline (std::cin,name);
std::cout << "Hello, " << name << "!\n";
return 0;
}
입력
jongmin kim
출력
Hello, jongmin kim!
공백문자까지 포함해서 전체가 출력
예시 2 : 구분자를 사용한 경우
#include <iostream>
#include <string>
int main ()
{
std::string name;
std::getline (std::cin,name,'m'); // 구분자 m 넘김
std::cout << "Hello, " << name << "!\n";
return 0;
}
입력
jongmin kim
출력
Hello, jong!
m 앞에서 잘린 것을 확인할 수 있다.
다시 문제 풀이로 돌아가서 각 테스트 케이스의 수학식을 파싱해보자면,
숫자 연산자 연산자 ... 형태지만 숫자는 char 하나가 아니라 0 이상 100 이하의 숫자이므로
double num;
cin >> num;
한번에 입력받는 것이 편리하다.
그러면 수학식에서 남은 부분은 연산자 연산자 ... 부분이고 각 연산자는 char 한 개의 형태를 띈다.
이 부분을 getline()을 통해 통으로 받아온 뒤 연산한다.
getline(cin, line);
for (char& c : line)
{
if (c == '@')
{
num *= 3;
}
else if (c == '%')
{
num += 5;
}
else if (c == '#')
{
num -= 7;
}
}
수학식의 결과는 소수점 둘째 자리까지 출력한다.
출력되는 수의 자릿수를 설정하기위해
std::fixed 와 std::setprecision()을 사용한다.
이전글(<iostream>의 조작자) 내용 참고
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
int T;
double num;
string line;
cin >> T;
for (int i = 0; i < T; i++)
{
cin >> num;
getline(cin, line);
for (char& c : line)
{
if (c == '@')
{
num *= 3;
}
else if (c == '%')
{
num += 5;
}
else if (c == '#')
{
num -= 7;
}
}
cout << fixed;
cout << setprecision(2) << num << '\n';
}
return 0;
}
cin과 getline() 함께 쓸 때 개행문자 남는 부분 처리에 대한 설명
https://unluckyjung.github.io/cpp/2020/02/14/cin.ignore/