如何在 C++ 中为这种情况编写严格的函数
How can I write a rigorous function for this case in C++
函数很简单,只需要一个格式为 (1,2) 的字符串,从中得到 1,2 作为两个整数。
但是怎么写才严谨呢?说可以 detech 无效输入。但是我不想一个字一个字的看,请问这个有默认的功能吗?
int main() {
int a, b;
if(std::scanf("(%d,%d)", &a, &b) != 2) {
// Error ! Recover or give up.
}
// a and b contain your values.
return 0;
}
这当然可以扩展到任何格式,但 std::scanf
正是您所需要的。
我知道的最简单的方法是 copy-paste 这些在 header 中,这让你 "stream in" 以直观的方式显示文字:
#include <iostream>
#include <string>
#include <array>
#include <cstring>
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&stringlit)[N]) {
std::array<e, N-1> buffer; //get buffer
in >> buffer[0]; //skips whitespace
if (N>2)
in.read(&buffer[1], N-2); //read the rest
if (strncmp(&buffer[0], stringlit, N-1)) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& charlit) {
e buffer; //get buffer
in >> buffer; //read data
if (buffer != charlit) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
return std::operator>>(in, carray);
}
那么你的代码就是这样:
if (stream >> '(' >> leftnum >> ',' >> rightnum >> ')' )
; //success
else
; //invalid input
一种更常见的方法是正则表达式:
std::string line;
std::getline(stream, line);
std::regex re("\(([0-9]+),([0-9]+)\)");
std::smatch match;
if (std::regex_match(stream, match, re) && match.size() > 1)
; //success
else
; //invalid input
函数很简单,只需要一个格式为 (1,2) 的字符串,从中得到 1,2 作为两个整数。
但是怎么写才严谨呢?说可以 detech 无效输入。但是我不想一个字一个字的看,请问这个有默认的功能吗?
int main() {
int a, b;
if(std::scanf("(%d,%d)", &a, &b) != 2) {
// Error ! Recover or give up.
}
// a and b contain your values.
return 0;
}
这当然可以扩展到任何格式,但 std::scanf
正是您所需要的。
我知道的最简单的方法是 copy-paste 这些在 header 中,这让你 "stream in" 以直观的方式显示文字:
#include <iostream>
#include <string>
#include <array>
#include <cstring>
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e(&stringlit)[N]) {
std::array<e, N-1> buffer; //get buffer
in >> buffer[0]; //skips whitespace
if (N>2)
in.read(&buffer[1], N-2); //read the rest
if (strncmp(&buffer[0], stringlit, N-1)) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
template<class e, class t>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, const e& charlit) {
e buffer; //get buffer
in >> buffer; //read data
if (buffer != charlit) //if it failed
in.setstate(in.rdstate() | std::ios::failbit); //set the state
return in;
}
//redirect mutable char arrays to their normal function
template<class e, class t, int N>
std::basic_istream<e,t>& operator>>(std::basic_istream<e,t>& in, e(&carray)[N]) {
return std::operator>>(in, carray);
}
那么你的代码就是这样:
if (stream >> '(' >> leftnum >> ',' >> rightnum >> ')' )
; //success
else
; //invalid input
一种更常见的方法是正则表达式:
std::string line;
std::getline(stream, line);
std::regex re("\(([0-9]+),([0-9]+)\)");
std::smatch match;
if (std::regex_match(stream, match, re) && match.size() > 1)
; //success
else
; //invalid input