如何检查返回函数和正确计算字符

时间:2013-11-01 08:42:38

标签: c++ chars

欢迎。我有两个问题。首先 - 函数大小bool(const char * pass)检查字符串内部字符的数量是否至少为8,但是有些错误。它总是显示最少8个字符,甚至字符串只包含3个字符。

我的工作是创建几个小函数来检查输入的字符串的正确性。你能用这个来帮助你吗?如果bool check(...)里面的所有小函数都返回true,我需要在控制台中写“STRING IS OKAY”。

我将不胜感激任何建议。

    #include <iostream>
    #include <cctype>     
    using namespace std;

    //Check the amount of chars
    bool size (const char* pass){
        if(sizeof(pass) > 7)
                        return true;
    }

    //Checks if the ASCII are located between 32 to 126
    bool isPrint (const char* pass){
        for(int x=0; x <= sizeof(pass); x++){
            if(isprint(pass[x]))
                return true;
        }
    }


    //Check the amount of numbers
    bool isNum (const char* pass){
        for(int x=0; x <= sizeof(pass); x++){
            if(isdigit(pass[x]))
                return true;
        }
    }

    //Check the amount of Upper letters
    bool isUpperLetter (const char* pass){
        for(int x=0; x <= sizeof(pass); x++){
            if(isupper(pass[x]))
                return true;
        }       
    }

    //Check the amount of lower letters
    bool isLowerLetter (const char* pass){
        for(int x=0; x <= sizeof(pass); x++){
            if(islower(pass[x]))
                return true;
        }       
    }

    //Check the amount of Punctuation Marks
    bool isPunctMark (const char* pass){
        for(int x=0; x <= sizeof(pass); x++){
            if(ispunct(pass[x])){
                return true;
            }
        }       
    }


    //All small moduls together
    bool check (const char* pass){
        size(pass);
        isPrint(pass);
        isNum(pass);
        isUpperLetter(pass);
        isLowerLetter(pass);
        isPunctMark(pass);
    }

    int main() {
        char x;
        cout << "Enter the string of characters" << endl;
        cin >> x;
        const char *password = &x;
        check(password);
    }

4 个答案:

答案 0 :(得分:4)

sizeof(pass)返回指针的大小。这是特定于实现的,如果您的函数始终返回true,我们可以猜测sizeof(char*)8,这意味着您有一个64位系统。

在许多其他系统上,它会返回4,甚至可能会返回21,具体取决于架构。

你可能想要检查指针所指向的字符串的长度,如下所示:

int len=strlen(pass);
if(len>=8)   //Check for >=8 is clearer than >7)
{
   return true;
}

您还可以迭代字符串并检查null。但是,当有一个很好的std库例程来完成这项工作时,为什么还要费心呢。

运行所有检查,执行类似

的操作
bool isValid(const char* const pass)
{
     if(!isPrint(pass))
     {

         return false;
     }
     if (!isNum(pass))
     {
         return false;
      }
     //etc
 }

你也可能有一个很长的

if(isPrint(pass)&&isNum(pass) .....)
{
    return true;
}

但这样会更麻烦,也更难调试。

答案 1 :(得分:3)

sizeof为您提供传递给它的对象类型的大小。它在编译时严格评估。您在const char *位系统上传递了8 64

要获取C样式字符串的长度,您可以使用标题C中的<cstring>函数strlen

那就是说,我建议这样做。我建议您从C字符串转移到C++ std::strings,因为它们更容易正确使用。

现在,你正在非常正确地使用C字符串!

int main() {
    char x;
    cout << "Enter the string of characters" << endl;
    cin >> x;
    const char *password = &x;
    check(password);
}

您阅读 charx),然后将其地址视为C字符串。现在这里有两个重大问题。

首先,你可能想要阅读多个角色。

其次,您将点击未定义的行为,并且您的计算机可能会爆炸,因为C字符串应该是指向NUL终止的数组的指针char。任何期望C字符串的函数都会循环查找'\0'所没有的结尾x,因为它首先不是数组。

因此,如果你使用std::string标题中的<string>,那么你可以拥有更安全的代码,而不需要指针,NUL - 终止符等等。

(未测试的)

// one of your functions for example
bool isUpperLetter (const std::string& s){
    for(int x=0; x < s.size(); ++x){ // Use <, not <=. C++ uses 0-indexing.
        if(isupper(s[x]))
            return true;
    }
    return false; // you forgot this!
}


int main() {
    std::string s;
    std::cout << "Enter a string:\n";
    std::cin >> s;

    isUpperLetter(s);
}

顺便说一句,如果您的输入字符串包含空格,但一次只有一件事,这将无效!

(如果您快速学习,请执行后续步骤:阅读std::getline<algorithm>标题。std::count_if看起来非常相关。)

在我们做到这一点时,尽早消除坏习惯,并阅读为什么要避免using namespace std;std::endl

修改

根据您的评论,您会遇到签名bool check(const char*),因此我猜您应该学习如何使用C字符串。让我们暂时假设你的导师知道他们在做什么。

然后,循环遍历C字符串的常规方法是使用指针,检查'\0'。因此,举例来说,要计算大写字母的数量(实际上,你不是这样写真实代码。或者至少,如果你试图在我正在研究的项目上,我强烈建议你修复它) :

int countUppercase (const char* c)
{
    if(NULL==c) return 0;

    int count = 0;
    for ( ; '\0' != *c ; ++c ) // loop while not found the NUL
    {
        if (isupper(*c))
            ++count;
    }

    return count;
}

如果你能逃脱它,我仍然强烈建议你阅读std::string。如果没有,那么你最好的选择可能是std::istream::getline

答案 2 :(得分:2)

您正在检查sizeof(pass),其大小为const char *。您应该迭代数组并查找str[i]=='\0'而不是。

修改 如建议的那样,您也可以使用strlen()函数。

答案 3 :(得分:1)

正如已经提到的那样,在函数的循环中使用sizeof指针而不是传递的字符串的实际长度。此外,有时候功能之前的评论与他们做或不做的事情不一致。例如

//Check the amount of numbers
bool isNum (const char* pass){
    for(int x=0; x <= sizeof(pass); x++){
        if(isdigit(pass[x]))
            return true;
    }
}

在评论中写有“检查数字的数量”。我认为你应该返回给定字符串中的位数。

所以我会按照以下方式重写函数

//Check the amount of numbers
size_t DigitCount ( const char* pass )
{
    size_t count = 0;

    for ( ; *pass; ++pass )
    {
        if ( isdigit( *pass ) ) ++count;
    }

    return count;
}