write a code for checking valid email address, - c++

i was writing a code on code blocks for checking a valid email address by checking following conditions:
1.must have at least one uppercase.
2.should have characters above 8 and less than 50
3.should have # sign
i have used 3 while loops for checking individual condition , but after entering the email address the program gets stopped . here is my code ,does anyone know what is the problem?
enter code here
#include<iostream>
using namespace std;
#include<stdio.h>
#include<conio.h>
void check_mail()
{
int i = 0;
char email[25];
int measure = 0;
cout<<" \n \n \n enter an email address ::";
gets(email);
while(email[i] != '\0')//for checking uppercsae //
{
if( (int)email[i] >= 65 && (int)email[i] <= 90)
{
measure = 1;
}
if( measure != 1)
{
cout<<"\n there is no uppercase letter in the email address ";
break;
}
}
while(email[i] != '\0') //checking # sign//
{
if((int)email[i] == 64)
{
cout<<" \n found the # character at :: "<<i<<endl;
}
}
int counter = 0;
while(email[i] != '\0')
{
counter = counter +1 ;
}
if(counter >=8 && counter <=50)
{
cout<< "\n valid number of characters are present in the mail :: ";
}
else if(counter <8)
{
cout<<" \n number of characters are less than 8 ";
}
else if(counter >=51 )
{
cout<<"\n the elements are greater than 50 ";
}
else
{
cout<<"\n enter a valid email address::";
}
}
int main()
{
cout<<" \n \n enter a email address ";
check_mail();
return 0;
}

This code below is a working and a way better implementation of your code:
#include <iostream>
#include <string>
bool check_mail(const std::string email)
{
if (email.size() < 8 || email.size() > 50) return false;
int upper_letters = 0;
for (int i = 0; i < email.size(); i++)
{
if (std::isupper(email[i])) upper_letters++;
if (email[i] == '#')
{
if (i < 8) return false;
else if (upper_letters == 0) return false;
return true;
}
}
return false;
}
int main()
{
std::cout << " \n \n Enter an email address ";
std::string email; std::cin >> email;
std::cout << check_mail(email) << std::endl;
return 0;
}
If you need to know what exactly caused the email to get rejected, you can do the following:
#include <iostream>
#include <string>
enum email_states { correct, under_char, over_char, no_upper, no_at_the_rate };
email_states check_mail(const std::string email)
{
if (email.size() < 8) return email_states::under_char;
else if (email.size() > 5) return email_states::over_char;
int upper_letters = 0;
for (int i = 0; i < email.size(); i++)
{
if (std::isupper(email[i])) upper_letters++;
if (email[i] == '#')
{
if (i < 8) return email_states::under_char;
else if (upper_letters == 0) return email_states::no_upper;
return email_states::correct;
}
}
return email_states::no_at_the_rate;
}
int main()
{
std::cout << " \n \n Enter an email address ";
std::string email; std::cin >> email;
std::cout << check_mail(email) << std::endl;
return 0;
}
For the 2'nd code, if the output is:
0 - correct
1 - under_char
2 - over_char
3 - no_upper
4 - no_at_the_rate
Also, using namespace std is considered as a bad practice. For more info on this look up to why is "using namespace std" considered as a bad practice.

You could consider using std::string and utilizing the standard library:
#include <iostream>
#include <string>
constexpr int kMinEmailCharacters = 8;
constexpr int kMaxEmailCharacters = 50;
constexpr char kAtSign = '#';
bool IsValidEmail(const std::string &email) {
auto email_length = email.length();
auto contains_uppercase = std::count_if(email.begin(), email.end(), isupper);
auto contains_at_sign = email.find(kAtSign) != std::string::npos;
return email_length > kMinEmailCharacters &&
email_length < kMaxEmailCharacters && contains_uppercase &&
contains_at_sign;
}
int main() {
std::cout << "Enter email: ";
std::string user_email;
std::cin >> user_email;
auto valid_email = IsValidEmail(user_email);
std::cout << "Valid email: " << (valid_email ? "true" : "false") << '\n';
return 0;
}
Example Usage 1:
Enter email: tejaspatil#mail.com
Valid email: false
Example Usage 2:
Enter email: Tejaspatil#mail.com
Valid email: true

There are some logic errors in the code:
in the first loop you print "there is no uppercase letter in the email address" when the first character is not an uppercase letter. You need to check all letters before you know if there was an uppercase
after the first loop, i is already at the end of the string, the next loop will not have a single iteration.
Further
use std::string
conio.h is windows only. You don't need it when you can use std::cin.
while(email[i] != '\0') is error-prone (you need to corrceclty manage the index, which your code fails to do). Use a range based loop instead
try to avoid magic numbers.
don't use C-style casts
in particular there is no need to cast the characters to int. You can compare directly to 'A' and 'Z'.
after you checked if the size of the input is <8 or >=8 && <=50 or >51 there is no other case, the else is superfluous.
Your code with this fixes:
#include<iostream>
using namespace std;
void check_mail()
{
int i = 0;
std::string email;
int measure = 0;
cout<<" \n \n \n enter an email address ::";
//gets(email);
std::cin >> email;
for (char c : email) {
if( c >= 'A' && c <= 'Z') { measure = 1; }
}
if( measure != 1) {
cout<<"\n there is no uppercase letter in the email address ";
//break;
}
for (char c : email) {
if(c == '#') {
cout<<" \n found the # character at :: "<<i<<endl;
}
}
int counter = email.size();
if(counter >=8 && counter <=50) {
cout<< "\n valid number of characters are present in the mail :: ";
}
else if(counter <8) {
cout<<" \n number of characters are less than 8 ";
}
else if(counter >=51 ) {
cout<<"\n the elements are greater than 50 ";
}
}
int main()
{
cout<<" \n \n enter a email address ";
check_mail();
return 0;
}
Produces expected output for input "Foo#bar.com":
enter a email address
enter an email address ::
found the # character at :: 0
valid number of characters are present in the mail ::
I suppose for the last output you also wanted to add email.size() to the output.

You consider using Regex for check email:
// C++ program for the above approach
#include <iostream>
#include <regex>
using namespace std;
// Function to check the email id
// is valid or not
bool isValid(const string& email)
{
// Regular expression definition
const regex pattern(
"(\\w+)(\\.|_)?(\\w*)#(\\w+)(\\.(\\w+))+");
// Match the string pattern
// with regular expression
return regex_match(email, pattern);
}
// Driver Code
int main()
{
// Given string email
string email = "mail#gmail.com";
// Function Call
bool ans = isValid(email);
// Print the result
if (ans) {
cout << email << " : "
<< "valid" << endl;
}
else {
cout << email << " : "
<< "invalid" << endl;
}
}

Related

When I input a number in char type, why i can't get a whole number?

I input a number in char type variable. like 12 or 22. but, console show me a 1 or 2.
How i get a whole number 12 ,22 in console?
#include <iostream>
int main()
{
using namespace std;
char a = 0;
cin >> a;
cout << a << endl;
return 0;
}
Here is console result.
12
1
C:\Users\kdwyh\source\repos\MyFirstProject\Debug\MyFirstProject.exe(프로세스 18464개)이(가) 종료되었습니다(코드: 0개).
이 창을 닫으려면 아무 키나 누르세요...
The reason I don't use int, string and something is because I want to get both number and Character in one variable.
So I want to see the results of combined numbers and character at the same time.
in that process i can't get a whole number.
#include <iostream>
using namespace std;
int index = 0;
constexpr int pagenum = 10;
void chapterlist(void);
void nextlist(void);
void beforelist(void);
void movechapter(char a);
int main(void)
{
char userin = 0;
bool toggle = 0;
cout << "결과를 볼 챕터를 고르시오." << endl;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cin >> userin;
if (userin == 'n')
{
backflash:
while(toggle == 0)
{
nextlist();
cin >> userin;
if (userin == 'b')
{
toggle = 1;
goto backflash;
}
else if (userin == 'n')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
while(toggle == 1)
{
beforelist();
cin >> userin;
if (userin == 'n')
{
toggle = 0;
goto backflash;
}
else if (userin == 'b')
continue;
else
{
system("cls");
movechapter(userin);
break;
}
}
}
else
{
system("cls");
movechapter(userin);
}
return 0;
}
void chapterlist(void)
{
int x = 0;
for (x = index + 1; x <= index + 10; x++)
cout << "Chapter." << x << endl;
}
void nextlist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index + pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void beforelist(void)
{
system("cls");
cout << "결과를 볼 챕터를 고르시오." << endl;
index = index - pagenum;
chapterlist();
cout << "다음 페이지로 이동: n" << endl;
cout << "이전 페이지로 이동: b" << endl;
}
void movechapter(char a)
{
cout << "선택한 Chapter." << a << "의 결과입니다." << endl;
}
In movechapter(), console show me a is 1 or 2, not 12, 22.
First, you have to understand what achar type is.
Character types: They can represent a single character, such as 'A' or '$'. The most basic type is char, which is a one-byte character. Other types are also provided for wider characters.
To simplify that, char can only hold one character.
Where as with your code, "12" is actually 2 separate characters, '1' and '2', and that's the reason it would not work.
Instead of declaring a as a char type, you could declare it as an int type, which is a type designed to hold numbers. So you would have:
int a = 0;
However, do note that int often has a maximum value of 2^31.
Or you could use std::string to store character strings. However, do note that if you wish to do any calculations to your string type, you would need to convert them to a number type first:
int myInt = std::stoi(myString);
Edit:
So I have re-checked your code after your update, there is nothing wrong with using std::string in your case. You can still check if user have input n or b by:
if (userin == "n")
Note that you would use double quotation mark, or "letter", around the content that you want to check.
On the other hand, you could use:
if(std::all_of(userin .begin(), userin.end(), ::isdigit))
To check if user have input a number.
Although char is just a number, it's presumed to mean "single character" here for input. Fix this by asking for something else:
int a = 0;
You can always cast that to char as necessary, testing, of course, for overflow.
You should be reading characters into a string, and then converting that string into an int. It would also probably make more sense to use something like getline() to read input, rather than cin >> a.
#include <string>
#include <iostream>
#include <stdexcept>
#include <stdio.h>
int main() {
std::string input_string;
/* note that there is no function that will convert an int string
to a char, only to an int. You can cast this to a char if needed,
or bounds check like I do */
int value;
while(1) {
getline(std::cin, input_string);
/* std::stoi throws std::invalid_argument when given a string
that doesn't start with a number */
try {
value = std::stoi(input_string);
} catch (std::invalid_argument) {
printf("Invalid number!\n");
continue;
}
/* You wanted a char, the max value of a `char` is 255. If
you are happy for any value, this check can be removed */
if (value > 255) {
printf("Too big, input a number between 0-255\n");
continue;
}
break;
}
printf("Number is %hhu\n", value);
}

How to check if a string contains all of these: digits, alphabets and special characters?

I'm trying to build a simple password validator:
Program prints
"Very weak" if password has less than 8 characters and all numbers.
"Weak" if password has less than 8 characters and all alphabets.
"Strong" if password has 8 or more characters and contains numbers and alphabets.
"Very strong" if password has 8 or more characters and contains numbers, alphabets and special characters.
As you can see, I know how to check if a string has either one of the three types of characters.
How can I check if a string has two or all three?
#include <iostream>
#include <ctype.h>
#include <cstring>
int main()
{
std::cout << "Enter your new password: ";
std:: string password{};
std::cin >> password;
bool veryweak;
bool weak;
bool strong;
bool verystrong;
if (password.length() < 8)
{
for (int i = 0; i < password.length(); i++)
{
if (isdigit(password[i]))
{
veryweak = true;
}
else if (isalpha(password[i]))
{
weak = true;
}
}
}
else if (password.length() >= 8)
{
for (int i = 0; i < password.length(); i++)
{
//if (password has digits and alphabets)
//strong = true;
//if (password has digits and alphabet and special characters)
//verystrong = true;
}
}
else
{
std::cout << "Password is invalid.";
}
//---------------------------------------------------------------------------------------------------------------------
if (veryweak)
{
std::cout << "Your password is very weak.";
}
else if (weak)
{
std::cout << "Your password is weak.";
}
else if(strong)
{
std::cout << "Your password is strong.";
}
else if (verystrong)
{
std::cout << "Your password is very strong.";
}
return 0;
}
I would introduce the booleans:
isShortPassword
containsNumbers
containsAlphabet
containsSpecialCharacters
than you can write
std::string passwortStrengt () {
if (isShortPassword && !containsAlphabet && !containsSpecialCharacters) {
return "weak";
//forumlate all cases as you did in prosa up above
} else if (...) {
} else if (...) {
}
return "weak"; // just in case you missed a case above
}
Why don't you use some counter like weakness_counter or something. For each property that is fulfilled, the counter is incremented by one. And at the end you check how much properties are fulfilled and rate the password strength after this.
Further I would recommend you to write an own function for each of your properties, like:
bool containsNumbers(string pw);
bool containsLetters(string pw);
And so on. In this case it's more easy to read, change and extend the code by new properties etc..
I hope I could help you.
Regards :)

Detect real numbers beyond whole numbers

This code is meant to detect REAL numbers from a string entered continuously by a user, and return the found real number as a double value . I was able to construct it to the point where it detects whole numbers, but if I try a decimal number it doesn't detect it. I think my error is within my isvalidReal() function, but I'm not sure how to move things around to get it to work.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main()
{
double getaReal(); //function prototype
int value;
cout << "Enter a number: ";
value = getaReal();
cout << "the number entered is a real number: " <<value << endl;
return 0;
}
bool isvalidReal(string str) //function to find real numbers.
{
int start = 0;
int i;
bool valid = true;
bool sign = false;
if (int(str.length()) == 0) valid = false; //check for empty string
if (str.at(0) == '-' || str.at(0) == '+') //check for sign
{
sign = true;
start = 1; //check for real num at position 1
}
if (sign && int(str.length()) == 1) valid = false; //make sure there's atleast 1 char after the sign
i = start;
while (valid && i<int(str.length()))
{
if (!isdigit(str.at(i))) valid = false; //found a non-digit character
i++; // move to next character
}
return valid;
}
double getaReal()
{
bool isvalidReal(string); //function declaration prototype
bool isnotreal = true;
string input;
while (isnotreal)
{
try
{
cin >> input; //accepts user input
if (!isvalidReal(input)) throw input;
}
catch (string e)
{
cout << "No real number has been detected, continue to\n enter string values: ";
continue; //continues user input
}
isnotreal = false;
}
return atof(input.c_str());
}

Validating User String User Input

So I've been trying to create this program that will take up to 12 digits from the user using string and string classes. The issue I'm having is:
Ignoring the (-) sign.
Ignoring the decimal point.
Giving an error when more than 12 digits are entered.
Only accepting digits (i.e no letters)
So far this is what I have:
#include <iostream>
#include <string>
#include <cctype>
#include <iomanip>
using namespace std;
bool test(char [] , int);
int main()
{
const int SIZE= 13;
char number[SIZE];
int count;
cout<< "Please enter a number up to "<< (SIZE-1) <<" digits long." << endl;
cout<< "The number may be positive or negative" << endl;
cout<< "and may include fractions (up to two decimal positions)" << endl;
cout<< "Sign and decimal dot(.) are not included in the digit count:"<< "\t";
cin.getline (number, SIZE);
if (test(number, SIZE))
{
while (number[count]!='\0')
{
cout<< "The currency value is: \t $";
cout<< setprecision(2) << number[count];
count++;
}
}
else
{
cout << "Invalid number: contains non-numeric digits.";
}
return 0;
}
bool test(char testNum[], int size)
{
int count;
for (count = 0; count< size; count++)
{
if(!isdigit(testNum[count]))
return false;
}
return true;
}
Any help is very much appreciated, but the most important to me at the moment is the 4th point. No matter what the input is, the output is "Invalid number:...." and I'm not sure why that is.
Your test function always test 13 chars even if the input is shorter.
Instead pass a string and use the range based for-loop so that you only test the valid chars - something like:
bool test(string testNum)
{
for (auto c : testNum)
{
if(!isdigit(c))
return false;
}
return true;
}
Further you should change your main-loop (where you print the value) as well, i.e. use string instead of char-array.
BTW - notice that this will only check for digits. Your description of the valid input format will require a more complex test-function.
For instance to check for sign you could add:
bool test(string testNum)
{
bool signAllowed = true;
for (auto c : testNum)
{
if (c == '-')
{
if (!signAllowed) return false;
}
else
{
if(!isdigit(c)) return false;
}
// Sign not allowed any more
signAllowed = false;
}
return true;
}
But you still need more code to check for the dot (.)
If you don't want to use a range-based for loop, you can do:
bool test(string testNum)
{
for (int i = 0; i < testNum.size(); i++)
{
if (testNum[i] == '-')
{
// Sign is only allowed as first char
if (i != 0) return false;
}
else
{
if(!isdigit(testNum[i])) return false;
}
}
return true;
}

Read digits from an int and counting them

Alright so I've been looking though Google and on forums for hours and can't seem to understand how to solve this problem.
I need to write a program that first determines if the number entered by the user is a base 5 number (in other words, a number that only has 0s, 1s, 2s, 3s, and 4s in it). Then, I have to count how many 0s, 1s, 2s, etc are in the number and display it to the user.
I've seen people saying I should convert int to a string and then using cin.get().
I noticed that I can't use cin.get() on a string, it needs to be a char.
I can only use a while loop for this assignment, no while... do loops.
Any help is appreciated!!
Here's what I have so far, obviously with all my mistakes in it:
//----------------------------------------------
// Assignment 3
// Question 1
// File name: q1.cpp
// Written by: Shawn Rousseau (ID: 7518455)
// For COMP 218 Section EC / Winter 2015
// Concordia University, Montreal, QC
//-----------------------------------------------
// The purpose of this program is to check if the
// number entered by the user is a base of 5
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
// Declaring variables
int number;
int zeros;
int ones;
int twos;
int threes;
int fours;
bool base5;
// Get data and calculate
cin >> number;
string numberString = to_string(number);
// Determine if the number is a base 5 number
while (cin.get(numberString) == 0 || cin.get(numberString) == 1 ||
cin.get(numberString) == 2 || cin.get(numberString) == 3 ||
cin.get(numberString) == 4)
base5 = true;
// Determine the number of each digits
zeros = 0;
ones = 0;
twos = 0;
threes = 0;
fours = 0;
return 0;
}
Several things you need to beware of:
One way to get a specific character from a std::string is by []. e.g.
std::string myString{"abcdefg"};
char myChar = myString[4]; // myChar == 'e'
cin.get(aString) is not trying to get data from aString. It continues to get data from stdin and store in aString. Once you have get the data and put into the string, you can simply manipulate the string itself.
a short piece of code that will count number of vowel in a string. If you can understand it, there should be no problem doing your work. (Haven't compiled, probably some typos)
std::string inputString;
std::cin >> inputString;
// you said you need a while loop.
// although it is easier to with for loop and iterator...
int i = 0;
int noOfVowels = 0;
while (i < inputString.length()) {
if (inputString[i] == 'a'
|| inputString[i] == 'e'
|| inputString[i] == 'i'
|| inputString[i] == 'o'
|| inputString[i] == 'u' ) {
++noOfVowels;
}
++i;
}
std::cout << "number of vowels : " << noOfVowels << std::endl;
Well you can try this approach. This will solve your needs I guess.
#include <iostream>
#include <string>
#include <sstream>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int number=0;
int zeros=0;
int ones=0;
int twos=0;
int threes=0;
int fours=0;
bool valid=true;;
int counter = 0;
cout<<"Enter the number: ";
cin >> number;
stringstream out;
out << number; //int to string
string numberString = out.str();
cout<<"\n\nNumber after string conversion : "<<numberString;
cout<<"\nPrinting this just to show that the conversion was successful\n\n\n";
while (counter < numberString.length())
{
if (numberString[counter] == '0')
zeros++;
else if(numberString[counter] == '1')
ones++;
else if(numberString[counter] == '2')
twos++;
else if(numberString[counter] == '3')
threes++;
else if(numberString[counter] == '4')
fours++;
else
valid=false;
counter++;
}
if(valid==true)
{
cout<<"\nZeros : "<<zeros;
cout<<"\nOnes : "<<ones;
cout<<"\nTwos : "<<twos;
cout<<"\nThrees : "<<threes;
cout<<"\nFours : "<<fours;
}
else
cout<<"\n\nInvalid data...base of 5 rule violated";
_getch();
return 0;
}
If you don't want to use std::string then use characters, first loop over the input from the user until ENTER is pressed.
char ch = 0;
while ((ch = cin.get()) != '\n')
{
...
}
For each character read, check if it is a digit (std::isdigit) and if it is in the range 0..4, if not quit and give some message of not being base 5
have an array of ints to keep track of the frequency of the digits
int freq[5] = {0,0,0,0,0};
after you have checked that the character is valid subtract the ascii value from the digit and use that as index in the array, increment that:
freq[ch - '0']++;
e.g.
char ch;
int freq[5] = {0};
while ((ch = cin.get()) != '\n')
{
cout << ch;
freq[ch-'0']++;
}
for (int i = 0; i < sizeof(freq)/sizeof(freq[0]); ++i)
{
cout << static_cast<char>(48+i) << ":" << freq[i] << endl;
}
Here's a useful function that counts digits:
// D returns the number of times 'd' appears as a digit of n.
// May not work for n = INT_MIN.
int D(int n, int d) {
// Special case if we're counting zeros of 0.
if (n == 0 && d == 0) return 1;
if (n < 0) n = -n;
int r = 0;
while (n) {
if (n % 10 == d) r++;
n /= 10;
}
return r;
}
In your code you can use this naively to solve the problem without any further loops.
if (D(n, 5) + D(n, 6) + D(n, 7) + D(n, 8) + D(n, 9) != 0) {
cout << "the number doesn't consist only of the digits 0..4."
}
cout << "0s: " << D(n, 0) << "\n";
cout << "1s: " << D(n, 1) << "\n";
cout << "2s: " << D(n, 2) << "\n";
cout << "3s: " << D(n, 3) << "\n";
cout << "4s: " << D(n, 4) << "\n";
You could also (or should also) use loops here to reduce the redundancy.