如何用C++为这种情况编写一个严格的函数

How can I write a rigorous function for this case in C++

本文关键字:一个 函数 C++ 何用 情况      更新时间:2023-10-16

函数很简单,只需取一个格式为(1,2)的字符串,就可以从中得到1,2作为两个整数。

但是如何写得严谨呢?比如可以检测到无效输入。但我不想一个字符一个字符地阅读,有没有默认的功能?

我知道的最简单的方法是将这些内容复制粘贴到标题中,这样可以直观地"流式输入"文本:

#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
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正是您所需要的。