Problem with boolean variable in email validation program [duplicate] - c++

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 3 years ago.
I am trying to create an email validation program without using the regex library. In one of my functions, I want to return a Boolean to check if there is an # sign in the email address and also if it is in a valid position (the # sign cannot be one of the first three characters of the string). However I am having problems with it because every time I run the program by entering in an email address with the # sign in an invalid position, it keeps telling me that the email is valid. Please help!
valid = checkEmail(email); //function call
if(valid == true)
cout << "Your email is valid!" << endl;
else
cout << "Your email is invalid!" << endl;
bool checkEmail(string email)
{
int counter;
int length;
bool firstThree; //checks to make sure # is not in the first three chars
counter = 0;
length = email.length();
firstThree = false;
for(int i = 0; i < length; i++)
{
if(email[i] == '#')
counter++;
}
for(int y = 0; y < length; y++)
{
if(email[0] == '#' || email[1] == '#' || email[2] == '#')
firstThree = true;
else
firstThree = false;
}
cout << "\n" << counter << endl; //check to see if counter works
if(counter != 1 && firstThree == true)
return false;
else
return true;
}

I guess you need to define the function bool checkEmail(string email) at the begining of the program. Basically flip if else and the function definition.
bool checkEmail(string email)
{
int counter;
int length;
bool firstThree; //checks to make sure # is not in the first three chars
counter = 0;
length = email.length();
firstThree = false;
for(int i = 0; i < length; i++)
{
if(email[i] == '#')
counter++;
}
for(int y = 0; y < length; y++)
{
if(email[0] == '#' || email[1] == '#' || email[2] == '#')
firstThree = true;
else
firstThree = false;
}
valid = checkEmail(email); //function call
if(valid == true)
cout << "Your email is valid!" << endl;
else
cout << "Your email is invalid!" << endl;

There seem to be a lot of beginner mistakes here, so I suggest learning the basics of programming and c++ first and like others suggested, use a debugger. Here are some of the mistakes:
Function definition
c++ is not like other common languages in the sense that functions need to be defined before they can be used. This means that you either need to move your checkEmail function above the function call, or create a separate definition above the function call like:
bool checkemail(string email);
as an exmaple.
Incorrect if-statement logic; Unnecessary for loop:
I'm assuming that based on how emails are formatted, you want the checkEmail function to return false if it doesn't match the correct formatting, and based on what your function currently does, that means that it will return false if the first three characters are # or if there isn't exactly one # symbol in the email. However, you used a && operator, which signifies and, meaning it will return true even when you don't want it to (much like how #Yastanub stated in his first comment). Better yet, that entire logic and if statement can be simplified greatly using std::string::find with a while loop and a vector (similar to this method):
vector<size_t> posVec;
size_t pos = email.find('#', 0); //note that this can be an int instead of size_t, but it can cause stack overflow with bigger numbers
while(pos != string::npos){
posVec.push_back(pos);
pos = email.find('#', pos+1);
}
switch(posVec.size()){
//if there is only one # symbol found
case 1:
bool firstThree = false;
for(int i = 0; i <= 2; i++)
//if there is only one # but it's in the first 3 positions, the email isn't valid
if(posVec[0] == i)
firstThree = true;
return !firstThree;
//otherwise the email doesn't work
default:
return false;
}
Remember to include the required libraries in order for this part to work:
#include <string>
#include <vector>
This also eliminates the second for loop in your function that is useless because the variable y is not being used, and the counter that was being used for testing
Another note
Using if (valid == true) is unnecessary as well. You can just use if (valid) because of how booleans work with if-statements.

Related

How to validate Name in flutter?

I want to allow only letter, space and dot(.) for Name filed input in a flutter project. No more than 5 spaces and 3 dots(.) will be allowed. How can I do that? I am new to programming, please help.
I know there are some geniuses out there who can solve the above problem in Regex. But not everyone is a genius. I always solve these tough regex problems by creating a function for myself that does the same.
Take a look at the function below. It summarizes what I wanted to explain
bool validation(String a){
int spaceNum = 0;
int dotNum = 0;
for (int i = 0; i < a.length; i++){
// check for valid characters
if(!"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ .".contains(a[i])){
return false;
}
// check for number of spaces
if (a[i] == " "){
spaceNum += 1;
if (spaceNum > 5){
return false;
}
}
// check for number of dots
if (a[i] == "."){
dotNum += 1;
if (dotNum > 3){
return false;
}
}
}
return true;
}
void main(){
print(validation("Wrong.validation. "));
print(validation("Wrong....validation"));
print(validation("Wrong1Validation12"));
print(validation("Correct Validation..."));
}
The above returns the following results:
false (because the number of spaces is more than 5)
false (because the number of dots is more than 3)
false (because there is a digit instead of a letter)
true

A loop never starts

I'm writing a simple function that is supposed to read an input from a user as a string. Check if the strings solely consist of digits then converts it to and int and returns it. The problem is the loop never used regardless of the input. I'm struggling to find the root of the problem.
int correctInt()
{
string temp;
int input;
bool m;
do
{
m = false;
getline(cin, temp);
int length=temp.length();
for (int a = 0; a < length; a++)
{
if (temp[a] < '0' && temp[a]>'9')
{
cout << "ID should consist of numbers. Try again: ";
m = true;
break;
}
}
if (!m)
{
return input = atoi(temp.c_str());
}
} while (1);
}
Thank you in advance
You should use OR instead of AND:
temp[a] < '0' || temp[a]>'9'
Try to change && (and) condition to || (or) condition
if (temp[a] < '0' || temp[a]>'9')

c++ getting weird crashes in my program [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
int a = 0, skrb = 0, j = 0;
char b, simboliai[2000];
char zodis[50][20];
char check[1][20] = {'f'};
cout << "Prasome irasykite sakini: ";
cin.getline(simboliai,sizeof(simboliai));
//----------------- Zodziu skaidymas ----------------------------------------------------------------------------------------------------------
a = 0;
for (int i = 0; i > -1; i++)
{
if ((simboliai[i] == 's' && simboliai[i++] == ' ') || (simboliai[i] == 's' && simboliai[i++] == '\n'))
{
check[0][a] = 't';
}
if (simboliai[i] == ' ')
{
a++;
}
else
{
zodis[i][a] = simboliai[i];
}
if (simboliai[i] == '\n')
{
break;
}
}
a = 0;
while (1)
{
if (simboliai[a] == '.' || simboliai[a] == ',' || simboliai[a] == '!' || simboliai[a] == '?')
{
skrb++;
}
a++;
if (simboliai[a] == '\n')
{
break;
}
}
a = 0;
cout << "Jus ivedete tokius zodius kurie baigiasi raide 's'" << endl;
while(1)
{
if (zodis[j][a] == 'Ì')
{
cout << '\n';
a++;
}
if (check[0][a] == 't')
{
cout << zodis[j][a];
}
if (zodis[0][a] == 'Ì')
{
break;
}
}
cout << "Pas jus yra (.','!'?) simboliu: " << skrb << endl;
cin.ignore();
cin.get();
}
Basically this program would work but that for part just ruins everything. It doesn't put characters one by one. And when I debug it shows that program have put symbol in its place but then there is Ì.
So it looks just like so
input: word word
zodis[0][0] goes like wÌÌÌÌÌÌÌÌÌÌ zodis [1][0] goes oÌÌÌÌÌÌÌÌÌÌ and so on and it breaks. Thank you in advance.
If you are saying the for loop wouldn't put characters 1 by 1, it was in your "simboliai[i++] == ' '" logic. integer 'i' been incremented twice each loop when current character is 's' which mean it will be incremented from i=2 to i=4 if simboliai[i] = 's'. Use i+1 instead for your checking.
for (int i = 0; i > -1; i++)
{
...
}
is the main problem. There might be others but I don't look too closely for them.
The values of i will be 0, 1, 2. etc.
All of them are greater than -1.
The loop will go on until the value i reaches INT_MAX. (Not sure what happens when i is incremented at that time).
That is way larger than the size of the array simboliai anyway. Your program will access the array simboliai beyond valid limits and cause undefined behavior.
I think what you need is:
size_t len = strlen(simboliai);
for (size_t i = 0; i < len; i++)
{
...
}
Other Problems
Some of the errors result from the assumption that there is a newline character in simboliai. That assumption is not correct. std::istream::getline reads and discards the newline character.
If Google Translate is correct, zodis is supposed to contain a list of words. When you are iterating over the characters of simboliai, you need three counters.
One to iterate over the characters of simboliai.
One to keep track of the number words.
One to keep track of the number of characters in the current word.
Your for loop is not doing that.
When you are trying to access the contents of an array, you need to always write defensive code and make sure that you never access the array using out of bounds indices. In the last while loop, you are not doing that.
In the last while loop, you are incrementing a only in the first if block. If the conditional of that if statement evaluates to false, a never gets incremented and you get stuck in an infinite loop.
In the last loop you use j as an index but its value is initialized to 0 at the start of the function and never gets updated. It's not clear what the intent of the last while loop is. Hence, I can't say whether it's a bug but it sounds like it could be.
Here's a cleaned up version of your posted code with still a few unknowns.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int a = 0, skrb = 0, j = 0;
char b, simboliai[2000];
char zodis[50][20];
char check[1][20] = {'f'};
cout << "Prasome irasykite sakini: ";
cin.getline(simboliai,sizeof(simboliai));
//----------------- Zodziu skaidymas ----------------------------------------------------------------------------------------------------------
int word_counter = 0;
a = 0;
size_t len = std::strlen(simboliai);
for (size_t i = 0; i < len; i++)
{
if ((simboliai[i] == 's' && simboliai[i+1] == ' ') || (simboliai[i] == 's' && simboliai[i+1] == '\0'))
{
check[0][a] = 't';
}
if (simboliai[i] == ' ')
{
zodis[word_counter][a] = '\0';
a = 0;
++word_counter;
}
else
{
zodis[word_counter][a] = simboliai[i];
++a;
}
}
a = 0;
while ( simboliai[a] != '\0' )
{
if (simboliai[a] == '.' || simboliai[a] == ',' || simboliai[a] == '!' || simboliai[a] == '?')
{
skrb++;
}
a++;
}
a = 0;
cout << "Jus ivedete tokius zodius kurie baigiasi raide 's'" << endl;
while( j < 50 && a < 20 )
{
if (zodis[j][a] == 'Ì')
{
cout << '\n';
}
if (check[0][a] == 't')
{
cout << zodis[j][a];
}
if (zodis[0][a] == 'Ì')
{
break;
}
a++;
}
cout << "Pas jus yra (.','!'?) simboliu: " << skrb << endl;
cin.ignore();
cin.get();
}

How to check string is only letters

I know that I can check if a "word" is all letters by:
bool checkAlpha(string str){
bool retVal;
for(int i = 0; i < str.size(); i++){
if(isalpha(str[i]) == 0){
retVal = true;
cout << "Input must only contain letters\n";
break;
}
else{
retVal = false;
cout << "all good\n";
}
}
return retVal;
}
Because of how I use the function return value, I need it to return TRUE if it is NOT all letters, and FALSE if it IS all letters. There's probably an easier way to do this but I just started C++ so this works for my current purpose.
My question is how do I check if a string is multiple "words"? When it reaches a space the function (correctly) says the space is not an alpha and tells me the input must only be letters. I tried doing
if((isalpha(str[i]) != 0) || (str[i] == " "))
and changing the "if" to return false (input only letters & space) and "else" to return true, but when I tried this I got a compiler error:
ISO C++ forbids comparison between pointer and integer [ -fpermissive]
So what can I do to get that a string of user input is only letters or space? (Preferably the simplest method)
This statement:
str[i] == " "
Is incorrect, it should be:
str[i] == ' '
but even better
isspace( str[i] )
as your condition does not check for other symbols like tab etc.
Also you have break in logic, in case you meet not alpha and not space you can set retVal to true (and also should terminate loop as you already got the answer), but you cannot set it to false otherwise. So your corrected code could be:
bool checkAlpha(const string &str){
bool retVal = false;
for(int i = 0; i < str.size(); i++){
if( !isalpha(str[i]) || !isspace(str[i]){
retVal = true;
cout << "Input must only contain letters\n";
break;
}
}
if( !retval )
cout << "all good\n";
return retVal;
}
if you do not need to provide diagnostic messages, function can be as simple as:
bool checkAlpha(const string &str){
for(int i = 0; i < str.size(); i++)
if( !isalpha(str[i]) || !isspace(str[i])
return true;
return false;
}
And your function name is confusing, based on return values it should be called checkNotAlpha
I guess it should be enought to fix it as follows:
if((isalpha(str[i]) != 0) || (str[i] == ' '))

Counting # of words in a line [duplicate]

This question already has answers here:
C++ function to count all the words in a string
(10 answers)
Closed 9 years ago.
This is what I am trying to do, this is not nearly the entire program I am making just a small portion. This part is counting the # of words of what I enter.
string s;
getline(cin, s);
for (unsigned int i = 0; i < s.length(); i++)
{
if (s[i] == ' ' || s[i] == '.')
{
numWords++;
}
}
This obviously works if someone enters a correct line with a period at the end. I can't think of how to get it to recognize the end of line character though, incase they don't put a period.
Why not just start the numWords counter on 1 and only count the spaces?
You can simply count the number of " " in your line and add that to 1. That's all.
bool previousSpace = false;
for (unsigned int i = 0; i < s.length(); i++)
{
if (isspace(s[i]) || s[i] == '.')
{
if (previousSpace == false)
{
numWords++;
previousSpace = true;
}
}
else
{
previousSpace = false;
}
}
cout << numWords + (previousSpace ? 0 : 1) << endl;
This considers more than one consecutive spaces. The key here is to use isspace function.
Could this be the same that you are after? Count the number of times each word occurs in a file or this already duplicate one Word count program in C++ duplicate?