input and range validation using strings, regular expressions, and lexical casting

Hello,

I'm new to C++ and I would like some tips on this overloaded type generic function template I wrote which does input and range based validation using strings and regular expressions and then recasts the value and returns it. The code works, but I'm wondering if there is anything that I can make better? Also is there a better way to do generic input and range validation using an overloaded function template like this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//  Author: Nikolas Britton;  Course: COSC 1337 Fall 2016 TT18;  Instructor: Thayer
//  Lab:  Input and Range Validation Template Function with Multi-Type Overloading.
//
//  Created by Nikolas Britton on 10/6/16.
//  Copyright © 2016 Nikolas Britton. All rights reserved.
//  License: MIT License

#include <iostream>
#include <regex>
#include <sstream>
#include <string>

using namespace std;

template <typename T>
inline T get_input (string message, string regexp) {
    
    regex pattern (regexp);
    string input_buffer = "";
    
    do {
        cout << message;
        getline (cin, input_buffer);
    } while (!regex_match (input_buffer, pattern));
    
    T value;
    istringstream (input_buffer) >> value;
    return value;
}

int main(int argc, const char * argv[]) {

    cout << get_input<int>("Please enter a positive integer number: ", "^[1-9]{1,4}$") << endl;
    cout << get_input<float>("Please enter a float number: ", "^[0-9].[0-9]{1,4}$") << endl;
    cout << get_input<double>("Please enter a double number: ", "^[0-9].[0-9]{1,4}$") << endl;
    cout << get_input<short>("Please enter a short negative int: ", "^-[0-9]{1,2}$") << endl;
    cout << get_input<char>("Please enter a char: ", "^.$") << endl;
    cout << get_input<string>("Please enter a string: ", "^.{2,254}$") << endl;
    cout << get_input<long long>("Please enter a long long integer number: ", "^[1-9][0-9]{2,100}$") << endl;
    
    return 0;
}
Last edited on
It appears to be fine.

Two small concerns that you may want to address:

When T is std::string, this may give unexpected results
1
2
3
T value;
istringstream (input_buffer) >> value;
return value;

Leading white spaces would be skipped, and the string would be truncated at the next white space character.


The validation of numbers can be more general. For instance, for int, the regex could be
1
2
3
4
5
// begin of string, zero or more white spaces, optional + or - sign,
// either a non-zero digit followed by zero to eight decimal digits or a single zero digit,
// zero or more white spaces, end of string 
// note: (?:) is a non-capturing group
const std::regex pattern( "^\\s*[+-]?(?:[1-9][0-9]{0,8}|0)\\s*$" ) ; 
Topic archived. No new replies allowed.