I'm doing a code with only C-String. This code is about to check if the password that the user input is correct in the following format: mmmDDYY.fl
mmm - three lowercase characters for month, e.g. "mar" is March (you don’t need to verify that it’s an actual month, just three lowercase characters)
DD - two digits for day
YY - two digits for year
. - a period
fl - two lowercase characters for first and last initials
On line 23 , I get the following error : Can you give me a further (better) explanation on that and how can I fix this? I have been reading things online since but not really understanding. Once I fix this I was about to use the same principle to check for YY.
Also, on line 27, I get the error :
Can you give me a further (better) explanation on that and how can I fix this?
#include <iostream> // preprocessor directive //
#include <cstring>
#include <cstdlib>
usingnamespace std;
int main()
{
constint maxChars = 128;
char password[maxChars];
int dFirstDigits, dSecondeDigits;
cout << "Enter the password : \n";
cin >> password; //nov1498.st password i'm testing
//check if the first three character are lowercase
if (!islower(password[0]) || !islower(password[1]) || !islower(password[2]))
{
cout << "The password format is not correct.\n";
return 1;
}
//converting character of password of index 3 and 4 to int and then check if they are digits
dFirstDigits = atoi(password[3]); // error here
//check if the character on index 7 is a "." (period)
if (password[7] != ".") // error here too
{
cout << "The password format is not correct.\n";
}
//check if the last two characters are in lowercase.
if (!islower(password[8]) || !islower(password[9]) || !islower(password[2]))
{
cout << "The password format is not correct.\n";
return 1;
}
return 0;
}
Line 23: atoi needs at parameter a pointer to a c-string, not a single char. But with password[3] you give to it a single char.
So if you want to convert your c-string since the 4th character, you need to pass a pointer to the c-string, pointing to the 4th position in the c-string: dFirstDigits = atoi( password + 3 );
Line 27: Here you have the opposite error, namely trying to compare a single char with a whole c-string.
Fix it by changing the double quotes by single quotes.
The double quotes are a shorthand for writing a C-string literal:
1 2 3
"." // is converts to array of two elements: {'.', 0}
'.' // is a single character
// 0, null, '\0' is not the same as printable character '0'
As said, the atoi() takes a C-string. Not a single character. When you give it string "1498.st" it is able to convert the four first characters into number 1498.
The dFirstDigits = password[3] - '0'; uses the fact that the printable digit characters are consecutive in the ASCII table: { ..., '0', '1', '2', '3', '4', ... }
As you don't actually need the value of the numeric digits, just check that these are digits - like checking for lower case. Also you can check that the length of the entered password is 10 chars.
cin >> password;
When using this with a c-style string, please don't. This has buffer overflow issues.
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
usingnamespace std;
int main()
{
constint maxChars {128};
char password[maxChars] {};
cout << "Enter the password: ";
cin.getline(password, maxChars);
if (strlen(password) != 10) {
cout << "The password format is not correct.\n";
return 1;
}
//check for lowercase
if (!islower(password[0]) || !islower(password[1]) || !islower(password[2]) || !islower(password[8]) || !islower(password[9])) {
cout << "The password format is not correct.\n";
return 2;
}
//check if the character on index 7 is a "." (period)
if (password[7] != '.') {
cout << "The password format is not correct.\n";
return 3;
}
//check index 3 and 4 if they are digits
if (!isdigit(password[3]) || !isdigit(password[4]) || !isdigit(password[5]) || !isdigit(password[6])) {
cout << "The password format is not correct.\n";
return 4;
}
cout << "The format is correct!\n";
}
> //check for lowercase
> if (!islower(password[0]) || ...
> //check index 3 and 4 if they are digits
> if (!isdigit(password[3]) || ...
Do not use functions from <cctype> (std::islower, std::isdigit etc.) with ordinary chars, particularly if they are read from input.
Like all other functions from <cctype>, the behavior of std::islower is undefined if the argument's value is neither representable as unsigned char nor equal to EOF. To use these functions safely with plain chars (or signed chars), the argument should first be converted to unsigned char https://en.cppreference.com/w/cpp/string/byte/islower#Notes