与 C++ 中 python 的 Input("msg") 类似的函数
Similar function to Input("msg") from python in C++
我想用 C++ 创建这个函数,input("x = ");,有点像 python,这个函数在 () 中打印消息并期望输入。它只能 bool,str,int,double。我想像这样制作一个结构输入
struct input {
std::string str;
int num;
double dub;
bool boolean;
input(const char *s) {
std::cout << s;
std::cin >> ### ; //here is my problem
}
};
但这就是我所得到的。我尝试了模板,但仍然无法理解。
提取输入应该不难,我会弄清楚的,现在我只想看看如何在结构中获取我的数据。
通常将 Python 翻译成 C++ 很困难,因为类型系统根本不同。然而,这不是问题。来自 documentation:
If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.
Python 的 input
不做任何转换。它只是 return 一个字符串。可以启用 EOF
异常,但它需要一些样板来在实际抛出异常时重置流异常设置。它可以在 RAII class 的帮助下完成,其唯一目的是重置流之前的异常设置,无论函数 returns 还是 throws.
struct eof_exception_enabled {
std::istream & inp;
std::ios::iostate old;
eof_exception_enabled(std::istream& inp) : inp(inp), old(inp.exceptions()) {
inp.exceptions(old | std::ios::eofbit);
}
~eof_exception_enabled() {
inp.exceptions(old);
}
};
std::string input(std::string prompt = "") {
std::cout << prompt;
std::string res;
auto inp = eof_exception_enabled{std::cin};
std::getline(inp.inp, res);
return res;
}
实际上,将输入流也传递给 input
会更符合习惯,这样就可以使用不同的流。不确定这对于提示用户并通常从标准输入读取的功能有多大意义。
如果您想启用转换,您可以使用一个函数模板,该模板利用字符串流进行转换:
template <typename T>
T from_string(const std::string& str) {
std::stringstream ss{str};
T t;
ss >> t;
return t;
}
用法是
auto age = from_string<int>( input("enter your age:"));
但是,正确处理由于意外输入导致的错误需要更多的时间。当从流中提取整数类型失败时,from_string
只执行 return 0
。不过,现在我们谈论的是转换,Python 中的转换也不是由 input
完成的。
我所做的是 class,
template <typename T> using couple = std::pair<bool, T>;
struct input {
std::string inp;
couple<std::string> str = {false, ""};
couple<int> num = {false, 0};
couple<double> dbl = {false, 0};
couple<bool> bl = {false, 0};
input(const char *s) {
std::cout << s;
std::cin >> inp;
fillinput(inp);
}
bool check_bool(std::string inputVal) {
transform(inputVal.begin(), inputVal.end(), inputVal.begin(), ::tolower);
if (inputVal == "false") {
bl.first = true;
bl.second = false;
return true;
}
if (inputVal == "true") {
bl.first = bl.second = true;
return true;
}
return false;
}
bool check_double(std::string inputVal) {
int dots = std::count(inputVal.begin(), inputVal.end(), '.');
bool digits = std::all_of(inputVal.begin(), inputVal.end(), ::isdigit);
if (dots == 1 && digits) {
dbl.first = true;
dbl.second = std::stod(inputVal);
return true;
}
return false;
}
bool check_int(std::string inputVal) {
bool digits = std::all_of(inputVal.begin(), inputVal.end(), ::isdigit);
if (digits) {
num.first = true;
num.second = std::stoi(inputVal);
return true;
}
return false;
}
void fillinput(std::string Input) {
if (check_int(Input) || (check_bool(Input)) || (check_double(Input)))
return;
else {
str.first = true;
str.second = Input;
}
}
};
需要做更多的工作才能使它可用,但就是这样。我知道它的代码不好,但它就是这样。
我想用 C++ 创建这个函数,input("x = ");,有点像 python,这个函数在 () 中打印消息并期望输入。它只能 bool,str,int,double。我想像这样制作一个结构输入
struct input {
std::string str;
int num;
double dub;
bool boolean;
input(const char *s) {
std::cout << s;
std::cin >> ### ; //here is my problem
}
};
但这就是我所得到的。我尝试了模板,但仍然无法理解。
提取输入应该不难,我会弄清楚的,现在我只想看看如何在结构中获取我的数据。
通常将 Python 翻译成 C++ 很困难,因为类型系统根本不同。然而,这不是问题。来自 documentation:
If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.
Python 的 input
不做任何转换。它只是 return 一个字符串。可以启用 EOF
异常,但它需要一些样板来在实际抛出异常时重置流异常设置。它可以在 RAII class 的帮助下完成,其唯一目的是重置流之前的异常设置,无论函数 returns 还是 throws.
struct eof_exception_enabled {
std::istream & inp;
std::ios::iostate old;
eof_exception_enabled(std::istream& inp) : inp(inp), old(inp.exceptions()) {
inp.exceptions(old | std::ios::eofbit);
}
~eof_exception_enabled() {
inp.exceptions(old);
}
};
std::string input(std::string prompt = "") {
std::cout << prompt;
std::string res;
auto inp = eof_exception_enabled{std::cin};
std::getline(inp.inp, res);
return res;
}
实际上,将输入流也传递给 input
会更符合习惯,这样就可以使用不同的流。不确定这对于提示用户并通常从标准输入读取的功能有多大意义。
如果您想启用转换,您可以使用一个函数模板,该模板利用字符串流进行转换:
template <typename T>
T from_string(const std::string& str) {
std::stringstream ss{str};
T t;
ss >> t;
return t;
}
用法是
auto age = from_string<int>( input("enter your age:"));
但是,正确处理由于意外输入导致的错误需要更多的时间。当从流中提取整数类型失败时,from_string
只执行 return 0
。不过,现在我们谈论的是转换,Python 中的转换也不是由 input
完成的。
我所做的是 class,
template <typename T> using couple = std::pair<bool, T>;
struct input {
std::string inp;
couple<std::string> str = {false, ""};
couple<int> num = {false, 0};
couple<double> dbl = {false, 0};
couple<bool> bl = {false, 0};
input(const char *s) {
std::cout << s;
std::cin >> inp;
fillinput(inp);
}
bool check_bool(std::string inputVal) {
transform(inputVal.begin(), inputVal.end(), inputVal.begin(), ::tolower);
if (inputVal == "false") {
bl.first = true;
bl.second = false;
return true;
}
if (inputVal == "true") {
bl.first = bl.second = true;
return true;
}
return false;
}
bool check_double(std::string inputVal) {
int dots = std::count(inputVal.begin(), inputVal.end(), '.');
bool digits = std::all_of(inputVal.begin(), inputVal.end(), ::isdigit);
if (dots == 1 && digits) {
dbl.first = true;
dbl.second = std::stod(inputVal);
return true;
}
return false;
}
bool check_int(std::string inputVal) {
bool digits = std::all_of(inputVal.begin(), inputVal.end(), ::isdigit);
if (digits) {
num.first = true;
num.second = std::stoi(inputVal);
return true;
}
return false;
}
void fillinput(std::string Input) {
if (check_int(Input) || (check_bool(Input)) || (check_double(Input)))
return;
else {
str.first = true;
str.second = Input;
}
}
};
需要做更多的工作才能使它可用,但就是这样。我知道它的代码不好,但它就是这样。