#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
using std::cin;
using std::cout;
using std::endl;
void parse_as_char(std::istream& is)
{
char c1 = '#', c2 = '#', c3 = '#';
is.clear();
is >> c1;
cout << "(1) c1='" << c1 << "', is.good()=" << is.good() << ", is.eof()=" << is.eof() << endl;
is >> c2;
cout << "(2) c2='" << c2 << "', is.good()=" << is.good() << ", is.eof()=" << is.eof() << endl;
is >> c3;
cout << "(3) c3='" << c3 << "', is.good()=" << is.good() << ", is.eof()=" << is.eof() << endl;
}
void parse_as_str(std::istream& is)
{
std::string s1 = "#", s2 = "#", s3 = "#";
is.clear();
is >> s1;
cout << "(1) s1=\"" << s1 << "\", is.good()=" << is.good() << ", is.eof()=" << is.eof() << endl;
is >> s2;
cout << "(2) s2=\"" << s2 << "\", is.good()=" << is.good() << ", is.eof()=" << is.eof() << endl;
is >> s3;
cout << "(3) s3=\"" << s3 << "\", is.good()=" << is.good() << ", is.eof()=" << is.eof() << endl;
}
void test_parse_as_str(const char* szInput)
{
std::istringstream ist;
cout << __FUNCTION__ << ": Input=\"" << szInput << "\"" << endl;
ist.str(szInput);
parse_as_str(ist);
cout << endl;
}
void test_parse_as_char(const char* szInput)
{
std::istringstream ist;
cout << __FUNCTION__ << ": Input=\"" << szInput << "\"" << endl;
ist.str(szInput);
parse_as_char(ist);
cout << endl;
}
bool parse_as_string_with_common_logic(std::istream& is, std::string& s, bool& bErr)
{
char c;
is >> c;
if (!is.good()) {
if (is.eof()) {
/*pass*/
}
else {
bErr = true;
}
return false;
}
is.unget();
is >> s;
return true; // 固定値trueを返すと最後のsが呼び出し元に正しく認識される。
// 最後のsを読み取り、入力に引き続く空白文字が無い場合は
// ここに来たとき!is.good()が成立しているため、is.good()を返すロジックはNG。
}
void test_parse_as_string_with_common_logic(const char* szInput, bool& bErr)
{
std::string str;
cout << __FUNCTION__ << ": Input=\"" << szInput << "\"" << endl;
std::istringstream ist;
ist.str(szInput);
size_t i = (size_t)0;
while (parse_as_string_with_common_logic(ist, str, bErr)) {
i++;
cout << "(" << i << ") str=\"" << str << "\", bErr=" << bErr << endl;
}
cout << "(" << "F" << ") str=\"" << str << "\", bErr=" << bErr << endl;
cout << endl;
}
int main()
{
bool bErr = false;
// ケースA)
cout << "Case A)" << endl;
test_parse_as_char("A B"); // Bの後ろに空白無し --> 'B' を読んだ後の is >> c3 で初めて!is.good()かつis.eof()成立(getc()と同じ挙動)
// ケースA')
cout << "Case A')" << endl;
test_parse_as_char("A B "); // Bの後ろに空白有り --> (同上)
// ケースB)
cout << "Case B)" << endl;
test_parse_as_str("A B"); // Bの後ろに空白無し --> "B" を読んだ時点で!is.good()かつis.eof()成立
// ケースC)
cout << "Case C)" << endl;
test_parse_as_str("A B "); // Bの後ろに空白有り --> "B" を読んだ後の is >> s3 で初めて!is.good()かつis.eof()成立(getc()と同じ挙動)
// 共通判定ロジックによるCase Bの読み取り
cout << "Case B with common logic:" << endl;
test_parse_as_string_with_common_logic("A B", bErr);
// 共通判定ロジックによるCase Cの読み取り
cout << "Case C with common logic:" << endl;
test_parse_as_string_with_common_logic("A B ", bErr);
}