#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <sstream>
using namespace std;
void solution(int n) {
string _push = "push";
string _pop = "pop";
string _empty = "empty";
string _size = "size";
string _top = "top";
stack<int> stk;
for (int i = 0; i < n; i++) {
string cmd;
cin.clear();
getline(cin, cmd);
if (cmd == _pop && !stk.empty()) {
cout << stk.top() << "\n";
stk.pop();
}
else if (cmd == _empty) {
if (stk.empty()) {
cout << "1" << "\n";
} else {
cout << "0" << "\n";
}
}
else if (cmd == _size) {
cout << stk.size() << "\n";
}
else if (cmd == _top && !stk.empty()) {
cout << stk.top() << "\n";
}
else {
string s_num;
stringstream _cmd(cmd);
_cmd >> cmd >> s_num;
cout << s_num << "!";
int num = stoi(s_num);
stk.push(num);
}
}
}
int main() {
int n;
cin >> n;
solution(n);
return 0;
}
⚠️ 에러
libc++abi: terminating due to uncaught exception of type std::invalid_argument: stoi: no conversion ![1] 29681 abort
💥 원인
- cin은 입력 버퍼에 개행문자(
\n)를 남겨둠- cin.clear()은 버퍼의 내용을 지우는 게 아니라, 스트림의 에러 플래그만 초기화함
- 즉, 입력 버퍼에
\n이 남아있어서 getline()이 실행되지 않고 바로 else문으로 넘어감- 숫자가 아닌 문자열이 stoi()에 전달되어 에러 발생
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <sstream>
using namespace std;
void solution(int n) {
string _push = "push";
string _pop = "pop";
string _empty = "empty";
string _size = "size";
string _top = "top";
stack<int> stk;
for (int i = 0; i < n; i++) {
string cmd, s_num;
cin.ignore();
getline(cin, cmd);
cout << cmd << endl;
if (cmd == _pop && !stk.empty()) {
cout << stk.top() << "\n";
stk.pop();
}
else if (cmd == _empty) {
if (stk.empty()) {
cout << "1" << "\n";
} else {
cout << "0" << "\n";
}
}
else if (cmd == _size) {
cout << stk.size() << "\n";
}
else if (cmd == _top && !stk.empty()) {
cout << stk.top() << "\n";
}
else {
stringstream _cmd(cmd);
_cmd >> cmd >> s_num;
if (cmd == _push) {
int num = stoi(s_num);
stk.push(num);
}
}
}
}
int main() {
int n;
cin >> n;
solution(n);
return 0;
}
🤔 시도
else { stringstream _cmd(cmd); _cmd >> cmd >> s_num; if (cmd == _push) { int num = stoi(s_num); stk.push(num); } }
- else문 안에서 다시
cmd == _push확인- cin.clear() 대신 cin.ignore() 사용하여 버퍼 초기화
- 근데 처음 명령어 받은 이후로 한 글자씩 잘림
💥 원인
- cin.ignore()은 첫 번째 문자 하나만 버퍼에서 지우고 나머지는 남겨둠
- 버퍼가 비어있는 경우 사용자의 입력을 기다림 -> 입력 받으면 첫 번째 글자는 지우고 나머지 문자열을 버퍼에 남겨둠
- cin 입력 → cin.ignore() → '\n' 제거 → getline() → 버퍼 비어있음 → cin.ignore() → getline() 시 입력에서 첫 번째 글자 제거
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <sstream>
using namespace std;
void solution() {
string _push = "push";
string _pop = "pop";
string _empty = "empty";
string _size = "size";
string _top = "top";
stack<int> stk;
vector<string> cmds;
string n;
getline(cin, n);
for (int i = 0; i < stoi(n); i++) {
string cmd;
getline(cin, cmd);
cmds.push_back(cmd);
}
for (auto cmd : cmds) {
if (cmd == _pop) {
if (stk.empty()) {
cout << "-1" << "\n";
} else {
cout << stk.top() << "\n";
stk.pop();
}
}
else if (cmd == _empty) {
if (stk.empty()) {
cout << "1" << "\n";
} else {
cout << "0" << "\n";
}
}
else if (cmd == _size) {
cout << stk.size() << "\n";
}
else if (cmd == _top) {
if (stk.empty()) {
cout << "-1" << "\n";
} else {
cout << stk.top() << "\n";
}
}
else {
string s_num;
stringstream _cmd(cmd);
_cmd >> cmd >> s_num;
if (cmd == _push) {
int num = stoi(s_num);
stk.push(num);
}
}
}
}
int main() {
solution();
return 0;
}
💭 해결
- cin이랑 getline이랑 같이 쓰면 입력을 정확히 못 받아서 그냥 getline만 씀
(일단은,,,,,,,,)- stack이 empty일 때 예외처리 수정
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <sstream>
using namespace std;
void solution(int n) {
string _push = "push";
string _pop = "pop";
string _empty = "empty";
string _size = "size";
string _top = "top";
stack<int> stk;
for (int i = 0; i < n; i++) {
string cmd, s_num;
getline(cin, cmd);
cout << cmd << endl;
if (cmd == _pop) {
if (stk.empty()) {
cout << "-1\n";
}
cout << stk.top() << "\n";
stk.pop();
}
else if (cmd == _empty) {
if (stk.empty()) {
cout << "1" << "\n";
} else {
cout << "0" << "\n";
}
}
else if (cmd == _size) {
cout << stk.size() << "\n";
}
else if (cmd == _top) {
if (stk.empty()) {
cout << "-1\n";
}
cout << stk.top() << "\n";
}
else {
stringstream _cmd(cmd);
_cmd >> cmd >> s_num;
if (cmd == _push) {
int num = stoi(s_num);
stk.push(num);
}
}
}
}
int main() {
int n;
cin >> n;
cin.ignore();
solution(n);
return 0;
}
💭 해결
- cin.ignore()은 cin 이후 한 번만 실행
💡 cin과 getline 차이
cin
- 공백, 탭, 개행문자를 구분자로 사용
- "hello world" 입력 시 "hello"만 읽음
- 개행문자를 버퍼에 남김
getline(cin, str):
- 개행문자(\n)까지 한 줄 전체를 읽음
- "hello world" 입력 시 "hello world"
전체를 읽음- 개행문자까지 모두 소비 (버퍼에서 제거)