【问题标题】:User Input Validation Using Character Array in C++在 C++ 中使用字符数组验证用户输入
【发布时间】:2020-01-02 18:23:33
【问题描述】:

我正在创建一个 c++ 程序来使用 c++ 中的函数验证书籍 ID。如果输入有效,程序必须返回 1,如果输入无效,程序必须返回 0。输入模式:“123-AB-12345”这将被视为有效输入。有效输入是: (a) 字符总数必须为 12 (b) 前三个字符必须是 1 到 9 的整数。 (c) 第 4 和第 7 个字符必须是后缀“-”。 (d) 最后 5 个字符必须是 1 到 9 的整数。

我尝试了以下方法,但没有得到想要的答案。需要帮助吗

#include<iostream>
using namespace std;
bool isValidBookId(char bookId[13]);
int main()
{
    char book[13];
    cin.getline(book,12);
    bool id = isValidBookId(book);
    cout<<id;
}
bool isValidBookId(char bookId[13])
{
    int i;
    bool check1,check2,check3,check4,check5,check6;
    check1=check2=check3=check4=check5=true;
    if(bookId[12]=='\0'){
        check1=true;
    }       
    if(bookId[3]=='-')
    {
        check2=true;
    }
    if(bookId[6]=='-')
    {
        check3=true;
    }
    for(i=0; i<3;i++){
        if(bookId[i]>=0 || bookId[i]<=9)
        {
            check4=true;
        }
    }
    if(bookId[i]>= 'A' || bookId[i]<= 'Z')
    {
        check5=true;
    }
    for(i=7; i<12; i++)
    {
        if(bookId[i]>=0 || bookId[i]<=9)
        {
            check6=true;
        }
    }
    if(check1==true && check2==true && check3==true && check4==true && check5==true && check6==true)
    {
        return true;
    }
    else
    {
        return false;
    }
}

【问题讨论】:

  • 您是否使用过调试器来查看哪个检查失败?你为什么要检查bookId[12] == '\0' inside 你的 for 循环?答案不会改变。此外,您将所有检查初始化为true,并且从不将任何检查设置为false
  • 哦,我刚刚删除了那个 for 循环,但我什至没有得到它。结果始终为 1。@ChrisMM 此外,我使用 bookId[12]=='\0' 在 char 数组(bookId[ ])的末尾标记一个空字符,以便用户只能输入 12 个字符(索引 0 到 11并且在索引 12 它显然是 '\0' (空字符)
  • 你永远不会初始化check6。如果您使用其未初始化和不确定的值,那么您有 未定义的行为
  • 另外注意,如果你有if (some_condition) return true; else return false;,那正好等于return some_condition;
  • 我还建议您查看character classification functions,例如std::isalnum

标签: c++ validation user-input


【解决方案1】:

您的代码中有一些错误。

首先,您将所有检查初始化为true,并且从未将任何内容设置为false,因此答案将始终为true。实际上,您希望将它们全部初始化为false,并在满足所有条件时更改为true,或者假设true,并在不满足条件时设置为false

其次,您对值0-9 的检查不正确。您无法将bookId[i]0 进行比较,您想将其与字符'0' 进行比较。另请注意,您的问题还说1-9 而不是0-9

第三,您对A-Z 的检查不正确(注意,此问题也适用于0-9)。你的代码基本上是bookId[i]大于或等于'A'或小于或等于Z,这总是将是true

我在下面写了你的代码:

bool isValidBookId( char bookId[13] ) {

    if ( bookId[12] != '\0' )
        return false;
    if ( bookId[3] != '-' )
        return false;
    if ( bookId[6] != '-' )
        return false;

    for ( int i = 0; i < 3; i++ ) {
        if ( bookId[i] < '1' || bookId[i] > '9' ) {
            return false;
        }
    }
    for ( int i = 4; i < 6; i++ ) {
        if ( bookId[i] < 'A' || bookId[i] > 'Z' ) {
            return false;
        }
    }
    for ( int i = 7; i < 12; i++ ) {
        if ( bookId[i] < '1' || bookId[i] > '9' ) {
            return false;
        }
    }

    return true;
}

此方法不需要任何布尔变量。相反,我假设true(最后一个return 语句)并尝试证明false。只要有false,您就可以返回而无需进行任何其他检查。

【讨论】:

    【解决方案2】:

    由于给定的代码是 C-Style 格式,我想介绍另外 2 个 C++ 解决方案。我认为无论如何,任务是考虑模式以及如何检测这些模式。

    在我的第一个解决方案中,我只是添加了更多 C++ 元素。第二种解决方案应该是正确的。

    请看:

    #include <iostream>
    #include <regex>
    #include <string>
    #include <cctype>
    #include <vector>
    
    bool isValidBookId1(const std::string& bookId) {
    
        // Lambda to detect hyphen
        auto ishyphen = [](int i){ return static_cast<int>(i == '-');};
    
        // First check size of given string
        bool result{(bookId.size() == 12)};
    
        // Define the position of the types
        std::vector<size_t> digitIndex{0,1,2,7,8,9,10,11};
        std::vector<size_t> letterIndex{4,5};
        std::vector<size_t> hyphenIndex{3,6};
    
        // Check types
        if (result) for (size_t index : digitIndex) result = result && std::isdigit(bookId[index]);
        if (result) for (size_t index : letterIndex) result = result && std::isupper(bookId[index]);
        if (result) for (size_t index : hyphenIndex) result = result && ishyphen(bookId[index]);
    
        // Return resulting value
        return result;
    }
    
    bool isValidBookId2(const std::string& bookId) {
    
        // Define pattern as a regex
        std::regex re{R"(\d{3}-[A-Z]{2}-\d{5})"}; 
    
        // Check, if the book id matches the pattern
        return std::regex_match(bookId, re);
    }
    
    int main()
    {
        // Get input from user
        if (std::string line{}; std::getline(std::cin, line)) {
            std::cout << "Check for valid Book input 1: " << isValidBookId1(line) << "\n";
            std::cout << "Check for valid Book input 2: " << isValidBookId2(line) << "\n";
        }
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-30
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 2015-07-13
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多