Добро пожаловать. У меня две проблемы. Во-первых — функция size 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);
}
sizeof(pass)
возвращает размер указателя. Это зависит от реализации, и если ваша функция всегда возвращает true, мы можем догадаться, что sizeof(char*)
является 8
, подразумевая, что у вас есть 64-битная система.
На многих других системах он вернется 4
или даже может вернуться 2
или же 1
в зависимости от архитектуры.
Вы, вероятно, хотите проверить длину строки, на которую указывает указатель, примерно так:
int len=strlen(pass);
if(len>=8) //Check for >=8 is clearer than >7)
{
return true;
}
Вы также можете перебрать строку и проверить на нулевое значение. Но зачем, когда есть хорошая библиотека 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;
}
но это будет сложнее и сложнее для отладки.
sizeof
дает размер типа объекта, переданного ему. Он оценивается строго во время компиляции. Вы передаете это const char *
, который 8
на 64
битовые системы.
Чтобы получить длину C
в стиле, вы можете использовать C
функция strlen
, в шапке <cstring>
,
Тем не менее, я бы порекомендовал не делая это. Я бы порекомендовал отойти от C
Строки для C++
std::string
s, потому что их гораздо проще правильно использовать.
Теперь, как есть, вы очень много используете C
строки неправильно!
int main() {
char x;
cout << "Enter the string of characters" << endl;
cin >> x;
const char *password = &x;
check(password);
}
Вы читаете не замужем char
(x
), затем возьмите его адрес и относитесь к нему как к 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
.
Вы проверяете sizeof(pass)
, который является размером const char *. Вы должны перебрать массив и проверить для str[i]=='\0'
вместо.
РЕДАКТИРОВАТЬ:
Как и предполагалось, вы также можете использовать функцию strlen ().
Как уже упоминалось, вы используете 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;
}