【问题标题】:How to apply validation on a string variable so that it accept only alphabetic data from the user?如何对字符串变量应用验证,以便它只接受来自用户的字母数据?
【发布时间】:2017-07-02 10:17:01
【问题描述】:

我想让用户只输入字母数据,而不是任何数字或特殊字符数据。那么如何应用验证呢?例如,在下面的代码中,我希望用户输入名称,并且名称不包含任何数字或特殊字符。我想让它只接受字母数据。

int main()
{
   string str;
   cout<<"Enter your name: ";
   cin>>str;
}

【问题讨论】:

  • 使用 getch() 在循环中读取一个字符
  • 读取字符串时,遍历其中的每个字符并检查它是否是字母。如果找到非字母数据,您可以选择忽略它、发出错误消息、丢弃整个字符串等。如果没有专门的硬件支持,就不可能让用户做任何事情(例如,如果用户的手指触摸非字母键)。
  • @Peter 谢谢

标签: c++ io


【解决方案1】:

一种方法是使用ctype.hcctype
Functions to determine the type contained in character data

例如:它只接受 alphabetic 甚至 space

std::string ui; // user input
std::getline( std::cin, ui );

bool vi = true; // validate input
for( const char& chr : ui ){
    if( !std::isalpha( chr ) ){
        vi = false;
        break;
    }
}

if( vi ){
    std::cout << "okay\n";
} else {
    std::cout << "NOT!\n";
}

另一种是使用std::regex
Regular expressions library (C++11)

例如:同样

std::string ui; // user input
std::getline( std::cin, ui );

bool vi = true; // validate input

//    for( const char& chr : ui ){
//        if( !std::isalpha( chr ) ){
//            vi = false;
//            break;
//        }
//    }

vi = std::regex_match( ui, std::regex( "[A-Za-z]+" ) );

if( vi ){
    std::cout << "okay\n";
} else {
    std::cout << "NOT!\n";
}  

你可以根据这些功能找到你需要的或者使用regexes

isalnum  
isalpha
islower 
isupper 
isdigit 
isxdigit 
iscntrl 
isgraph
isspace 
isblank
isprint
ispunct

第三种方式可以使用std::string::find

例如:

std::string ui; // user input
std::getline( std::cin, ui );

bool vi = true; // validate input

// find
// rfind
// find_first_of
// find_first_not_of
// find_last_of
// find_last_not_of

const char* not_valid_input = "!@#$%^&*()_+,.";
while( *not_valid_input ){

    if( ui.find( *not_valid_input ) < ui.size() ){
        vi = false;
        break;
    }

    ++not_valid_input;
}


if( vi ){
    std::cout << "okay\n";
} else {
    std::cout << "NOT!\n";
}

还有第四种方法是使用std::find_if,但否定版本

std::string ui; // user input
std::getline( std::cin, ui );

bool vi = true; // validate input

vi = std::find_if_not( ui.begin(), ui.end(), ::isalpha ) == ui.end();

if( vi ){
    std::cout << "okay\n";
} else {
    std::cout << "NOT!\n";
}

注意:EX: 中的c++11 for-loop 等同于:

for( unsigned index = 0; index < ui.size(); ++index ){
    if( !std::isalpha( ui[ index ] ) ){
        vi = false;
        break;
    }
}

【讨论】:

  • 谢谢。有用。在第一个示例中,请解释第 4 行发生了什么? for( const char&amp; chr : ui )if( !std::isalpha( chr ) ){ vi = false; break; } 中的 chr 是什么?
  • @IBTEHAAJSHAHID 你的意思是for( const char&amp; chr : ui )
  • 我不明白for( const char&amp; chr : ui )发生了什么
  • 在冒号之前,你初始化了chr,对吧?
  • 冒号的作用是什么?
【解决方案2】:

当循环可以被命名良好的算法替换时,通常认为避免循环是一种很好的做法。请参阅 Sean Parent 的演讲,他的口头禅是“没有原始循环”。

这里的一种方法是使用std::all_of,它会检查字符串并在谓词返回 false 时立即停止循环。

#include <cctype>

#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s;
    cout << "enter a string using only characters from the alphabet.\n";

    cin >> s;

    if(all_of(begin(s), end(s), ::isalpha))
        cout << "all ok!!\n";
    else
        cout << "the string contains some non alpha characters.\n";
}

all_of 是 c++11 及更高版本(我们真的还需要添加免责声明吗),但是如果您没有可用的标准库实现,则该功能实现起来很简单。

另请注意,这使用cin,因此如果该行包含它们,则只读取第一个空格。如果您想阅读整行,请使用std::getline

【讨论】:

  • 我猜 std 在 c++ 中没有成员“readline”。不是和c#有关吗?
  • @Pual std 没有 readline 。你能给我们一个参考吗?或者您可能想说getline
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2015-01-27
  • 2012-01-09
  • 2014-06-06
  • 2013-04-28
相关资源
最近更新 更多