1

いらっしゃいませ。2 つの問題があります。最初に - 関数 size bool (const char * pass) は、文字列内の文字の量が少なくとも 8 であるかどうかを確認しますが、何か問題があります。文字列に3文字しか含まれていない場合でも、最小8文字があることを常に示しています。

私の仕事は、入力された文字列の正確性をチェックするためのいくつかの小さな関数を作成することです。これを手伝ってくれませんか?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

4 に答える 4

4

sizeof(pass)ポインタのサイズを返します。sizeof(char*)これは実装固有のものであり、関数が常に true を返す場合、それはであると推測でき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;
}

しかし、それはより厄介で、デバッグが難しくなります。

于 2013-11-01T08:45:43.710 に答える
3

sizeof渡されたオブジェクトの型のサイズを示します。コンパイル時に厳密に評価されます。ビットシステム上const char *にあるを渡しています。864

スタイルの文字列の長さを取得するには、ヘッダーで関数,Cを使用できます。Cstrlen<cstring>

つまり、これを行わないことをお勧めします。C文字列からC++ std::stringsに移動することをお勧めします。正しく使用する方がはるかに簡単だからです。

今のままでは、C文字列を正しく使用していません!

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

単一の char( )を読み取り、xそのアドレスを取得して、これをC文字列として扱います。ここで 2 つの重大な問題が発生します。

まず、おそらく複数の文字を読むつもりでした。

次に、undefined behaviorにヒットし、文字列は の で終わる配列Cへのポインターであると想定されるため、コンピューターが爆発する可能性があります。文字列を期待するすべての関数は、そもそも配列でさえないため、末尾にないを探してループします。NULcharC'\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);
}

ところで、入力文字列にスペースが含まれている場合、これは機能しませんが、一度に 1 つのことです!

(すぐに学習した場合の次のステップ: 読んstd::getlineで、<algorithm>header.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あなたがそれで逃げることができるなら、私はまだaに読むことを強くお勧めします. そうでない場合、次善の策はおそらくstd::istream::getline.

于 2013-11-01T09:00:22.523 に答える
2

sizeof(pass)const char* のサイズである をチェックしています。配列を反復処理し、代わりに chack する必要がありstr[i]=='\0'ます。

編集: 提案されているように、代わりに strlen() 関数を使用することもできます。

于 2013-11-01T08:45:20.520 に答える
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;
}
于 2013-11-01T09:06:44.293 に答える