C ++ проверяет значение текстового поля в приложении - PullRequest
0 голосов
/ 04 октября 2018

Я работаю над приложением с картой и не хочу, чтобы человек мог ввести недопустимую точку на карте (например, широта и долгота).

Допустим, у вас есть панель, которая выглядитчто-то вроде этого.Обратите внимание, не по кодам, как это выглядит, просто как это будет выглядеть, если вы посмотрите на приложение:


                                    [My great application]

                                     Textbox1 [XX:XX:XX]

                                     Textbox2 [XX:XX:XX]

                                     Textbox3 [XX:XX:XX]

                                     Pushbutton [APPLY]

Моя главная проблема

У меня нет возможности узнатьесли то, что кто-то вводит, находится прямо в текстовых полях.Мой TextBox ожидает 3 набора целых чисел [XX: XX: XX].Ничто не ниже 00, и ничто не выше 99 (строго 2 цифры).Для этого примера я покажу только int, чтобы он был коротким:

int myInt = NULL; //Don't want garbage data here
bool isValid = false;

//Gets input and sets textbox to myInt

std::string myString = std::to_string(myInt); //Cast int to a string
If(myString.length() - 1 == 0) //NULL intToString.length() == 1?
{
    std::cout << "Incorrect, please try again" << std::endl;
}
else
{
    isValid = true;
}

if(isValid)
{
    //applyChanges(); <-- MY INTS WOULD GO INTO THIS
}

, тогда я быстро понял, что 0-9 полностью допустимы.(00, 01, ..., 09).Так что это не сработает.


Мой вопрос

Как мне проверить, правильно ли введенные пользователем данные?Это не совсем имеет смысл для меня.Я не уверен, что еще я могу сделать, кроме проверки длины.

В общем, я хочу найти способ получить условие, чтобы, когда все хорошо, ТОГДА isValid = true;


Примечания

  1. Я могу получить прямой доступ ко всем данным в текстовых полях
  2. У меня есть возможность проверить на получение или потерю фокуса

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я согласен с markhc, но вам также может понравиться использование регулярного выражения .Преимущество состоит в том, что тот же код может использоваться для проверки ввода другого типа, и, конечно, он намного короче.

Вот код (части, украденные у markhc!):

#include <regex>
#include <string>
#include <iostream>
using namespace std;

int main()
{
    string regx = R"([0-9]{2}:[0-9]{2}:[0-9]{2})";
    smatch matches;

    // some test data
    std::vector<std::string> inputs{
        "00:00:00",
        "99:99:99",
        "1:00:00",
        "AA:00:00",
        "0B:0000",
        "0B:00c00",
    };

    // Run tests and print result
    for (auto& input : inputs) {
        if (regex_search(input, matches, regex(regx)))
        {
            std::cout << input << " - Valid!" << std::endl;
        }
        else {
            std::cout << input << " - Invalid!" << std::endl;
        }
    }
}

Это также приводит к выводу:

00:00:00 - Valid!
99:99:99 - Valid!
1:00:00 - Invalid!
AA:00:00 - Invalid!
0B:0000 - Invalid!
0B:00c00 - Invalid!

Регулярное выражение [0-9]{2}: [0-9] {2}: [0-9] {2} поясняется ниже.

[0-9] означает цифру 0-9

{2} означает2 раза

: означает необходимый вам разделитель

Чтобы показать, насколько гибкими являются регулярные выражения: ..Если вам нужен другой формат, например 000: 0000, например, вам просто нужно изменитьрегулярное выражение в [0-9] {3}: [0-9] {4} и код остается прежним.

0 голосов
/ 04 октября 2018

Вот решение, которое я придумал.Дайте мне знать, если я неправильно понял вашу проблему.

Алгоритм прост:

  1. Разбивает входные данные на 3 части;
  2. Убедитесь, что длина каждой из них составляет 2 цифры;
  3. Преобразовать в целое число и убедиться, что оно находится в пределах диапазона;

#include <iostream>
#include <string>
#include <vector>
#include <sstream>

// Simple string split algorithm
std::vector<std::string> string_split(
    std::string const& str, 
    char delimiter) 
{
    std::istringstream       ss{str};
    std::vector<std::string> result;
    std::string              line;

    while(std::getline(ss, line, delimiter)) {
        result.emplace_back(std::move(line));
    }

    return result;
}

// Validates the input
bool isValid(std::string const& input) {
    // Split string on each ':'
    // 00:00:00
    //   ^  ^
    auto substr = string_split(input, ':');

    // If there are not 3 parts, its malformed
    if(substr.size() != 3) 
        return false;

    // For reach result...
    for(auto const& str : substr) {
        // If it is not 2 digits long, error.
        if(str.size() != 2) 
            return false;

        try {
            // Try converting it to an integer
            // This throws on failure
            auto value = std::stoi(str);

            // make sure its within range
            return value >= 0 && value <= 99;
        } catch(...) {
            // Failed to convert
          return false;
        }
    }

    return true;
}

int main()
{
    // Some tests
    std::vector<std::string> inputs{
        "00:00:00",
        "99:99:99",
        "1:00:00",
        "AA:00:00",
        "0B:0000",
        "0B:00c00",
    };

    // Run tests and print result
    for(auto& input : inputs) {    
        if(isValid(input)) {
            std::cout << input << " - Valid!"<< std::endl;  
        } else  {
            std::cout << input << " - Invalid!"<< std::endl;  
        }
    }
}

Результаты:

$g++ -o main *.cpp
$main
00:00:00 - Valid!
99:99:99 - Valid!
1:00:00 - Invalid!
AA:00:00 - Invalid!
0B:0000 - Invalid!
0B:00c00 - Invalid!

Надеюсь, это поможет,

Приветствие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...