Validating Password Loop using control structures - c++

I am trying to create a program where a string (password) is read from the terminal.
the password has to be atleast 8 char long, must have an upper and lower case letter, a digit and no space.
here's the code:
#include <iostream>
#include <string>
using namespace std;
int main() {
string pw;
char i;
bool hasLow=0, hasUpp=0, hasdigit=0, hasspace=0, status=0;
do {
cout<<"What will be your password?"<<endl;
getline (cin,pw);
for (int i = 0; i < pw.length(); i++) {
if (isupper(pw[i])) hasUpp =1;
if (islower (pw[i])) hasLow=1;
if (isdigit(pw[i])) hasdigit=1;
if (!(isspace (pw[i]))) hasspace=1; }
cout<<"password is invalid. Please try again."<<endl;
}
while ( (hasUpp) && (hasLow) && (hasdigit) && (hasspace) && (pw.length() >= 8));
{cout<<"Password is valid";} }
I can't get the do while loop to work (has to be do while) and the password is accepted even if there is a space

You are not resetting your bools on each loop iteration. Your loop condition is wrong. And your invalid message is in the wrong place.
Try this instead:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
int main() {
string pw;
char ch;
bool hasLow, hasUpp, hasdigit, hasspace;
do {
cout << "What will be your password?" << endl;
getline (cin, pw);
hasLow = hasUpp = hasdigit = hasspace = false;
for (size_t i = 0; i < pw.length(); ++i) {
ch = pw[i];
if (isupper(ch)) hasUpp = true;
else if (islower(ch)) hasLow = true;
else if (isdigit(ch)) hasdigit = true;
else if (isspace(ch)) hasspace = true;
}
if ((hasUpp) && (hasLow) && (hasdigit) && (!hasspace) && (pw.length() >= 8))
break;
cout << "password is invalid. Please try again." << endl;
}
while (true);
cout << "Password is valid";
}
Online Demo

Related

C++ arrays, expression must have a constant value

Ok, so I am new to coding and am trying to learn c++. I am making a program to verify a password has uppercase, lowercase, and a number. I feel that the solution will be a simple one but I cannot for the life of me work it out.
using namespace std;
string password ="";
cin >> password;
I can validate this fine. I then want to convert the password to an array of chars so I can check each character of the password. I start with:
char passwordHolder[password.length()];
but I get the error:
expression must have a constant value
From looking at other forum responses I think it has something to do with visual studio as a compiler not being able to handle variable arrays, though I don't really understand how/why this happens, or how to work around this.
Another post suggests using the new operator but I don't understand fully how to implement this into my code in a way that works.
Any help is appreciated.
Ah I finally got it. Thanks to user4581301 for telling me that a string already is an array of characters. This hint gave me ideas of how to solve the problem.
I actually managed to get rid of the new array entirely and instead search through the string.
instead of char passwordHolder[password.length()]; I could get rid of that entirely.
My initial plan was to search the passwordHolder array with:
for (int i = 0; i < password.length(); i++){
if (isupper(passwordHolder[i])){
hasUpper= true;
}
if (islower(passwordHolder[i])){
hasLower= true;
}
if (isdigit(passwordHolder[i])){
hasDigit = true;
}
}
if (hasLower == true && hasUpper == true && hasDigit == true)
return 1;
but seeing as I no longer need the passwordHolder array, I could instead use password as the array and do:
for (int i = 0; i < password.length(); i++) {
if (isupper(password[i]))
hasUpper = true;
else if (islower(password[i]))
hasLower = true;
else if (isdigit(password[i]))
hasDigit = true;
}
if (hasLower == true && hasUpper == true && hasDigit == true)
return 1;
Thank you to those who commented. I had been stuck on this for like 3 hours lol.
If you are also having issues with this task, my full solution is here. Probably still very scruffy but it works:
#include <iostream>
#include <string>
using namespace std;
string password = "";
string confirmPassword = "";
bool hasDigit = false;
bool hasUpper = false;
bool hasLower = false;
int x = 0;
int confirm(string password, bool hasUpper, bool hasLower, bool hasDigit)
{
for (int i = 0; i < password.length(); i++) {
if (isupper(password[i]))
hasUpper = true;
else if (islower(password[i]))
hasLower = true;
else if (isdigit(password[i]))
hasDigit = true;
}
if (hasLower == true && hasUpper == true && hasDigit == true)
return 1;
}
int main(string password, bool hasUpper, bool hasLower, bool hasDigit) {
Start:
cout << "please enter your password: ";
cin >> password;
cout << "please confirm your password: ";
cin >> confirmPassword;
while (password != confirmPassword || password.length() < 8) {
cout << "Passwords do not match. Please enter your password again: ";
cin >> password;
cout << "Please confirm your password: ";
cin >> confirmPassword;
}
x = confirm(password, hasUpper, hasLower, hasDigit);
if (x == 1) {
cout << "You have a good password";
}
else {
cout << "You should have a password with 8 characters or more, a Capital letter, lowercase letter, and a number. Try again. \n";
goto Start;
}
}

Checking if alphabetic string is a palindrome in C++

I've attempted to write a code that checks whether or not a string is a palindrome. Here is the code:
#include <iostream>
#include <string>
using namespace std;
bool pal(string str)//This block of code checks if input string is a palindrome
{
bool valid;
int i;
for (i = 0; i < str.length(); i++)
{
if (str[-i] == str[i])
{
valid = true;
}
else
{
valid = false;
}
}
return valid;
}
int main()
{
string s;
cin >> s;
if (!pal(s))
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
}
return 0;
}
Currently I am getting "Debug Assertion Fail" error.
str[-i] == str[i]
is a problem since negative indices are not valid indices in C++.
You need to change the strategy a little bit.
bool pal(string str)
{
int i = 0;
int j = str.length() - 1;
for ( ; i < j; ++i, --j)
{
if (str[i] != str[j])
{
// No need for any more checks.
return false;
}
}
// If we come here, the string is a palindrome.
return true;
}
C++ Provides us with an inbuilt function reverse() which can be used to reverse the Input string and compare it with un reversed string and print the output. The code goes as follows.
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
string str;
cin>> str;
string rev;
rev = str;
reverse(str.begin(), str.end()); // string reverse operation
if(rev == str){
cout<<"YES"<<endl; // Prints "Yes" if string is palindrome
}else{
cout<<"NO"<<endl; // Prints "No" if string is not palindrome
}
return 0;
}

I am getting a segmentation fault in this code and can't understand why?

I am trying to code a program where it takes a program as an input and prints out all the comments written in that program in a separate line.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string str;
while(getline(cin,str)) {
int i;
// cout<<str;
for(i=0;str[i]!='/' && str[i+1] !='/';i++);
//cout<<i;
for(i;str[i]!='\n';i++) {
// cout<<i;
cout<<str[i];
}
cout<<endl;
}
return 0;
}
I am getting a segmentation fault in this code and I can't understand why. This is part of a code of a problem in hackerrank https://www.hackerrank.com/challenges/ide-identifying-comments/copy-from/12957153
As commented in your question your code is wrong. First you are treating std::string object, returned by getline, as character array. Secondly your for loops never end if there is no // or \n found in input string. So obviously it will crash. Below is the modified code.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
string str;
while(getline(cin,str)) {
int i;
// cout<<str;
size_t len = str.length();
const char *cstr = str.c_str();
for(i=0; (cstr[i]!='/' && cstr[i+1] !='/' && i < len); i++)
//cout<<i;
for(; cstr[i]!='\n' && i < len;i++) {
// cout<<i;
cout<<cstr[i];
}
cout<<endl;
}
return 0;
}
int main() {
while(getline(cin,str)) {
int i, len = str.size();
//always make sure that you are not accessing
//contents after your string has ended
for(i=0; i < (len - 1) && !(str[i] == '/' && str[i+1] == '/'); i++);
//note that i here might be the last alphabet
//if there's no comment
if(i < len && str[i] != '/')
i++;
//checking if str[i] != '\n' is not a good idea
//as c++ stl strings are not temrinated by '\n'
if(i < len) {
for(; i < len; i++)
cout << str[i];
cout << endl;
}
}
return 0;
}
Also note that both of the following codes won't terminate at the 4th character, c++ stl strings are not terminated by these characters.
string str = "hahahaha";
str[4] = '\n';
cout << str;
str[4] = '\0';
cout << str;
This is much easier to write and probably much faster than the other solutions to date.
#include <iostream>
int main()
{
std::string str;
while (std::getline(std::cin, str))
{
size_t loc = str.find("//");
if (loc != str.npos)
{
std::cout << str.substr(loc + 2)<< std::endl;
}
}
return 0;
}
It is also wrong.
Here is a nice, clean, and simple state machine version. Also pretty close to worst-case for speed. Thing is it's closest to being right, even though it is also wrong.
#include <iostream>
enum states
{
seeking1,
seeking2,
comment
};
int main()
{
std::string str;
while (std::getline(std::cin, str))
{
states state = seeking1;
for (char ch:str)
{
switch (state)
{
case seeking1:
if (ch == '/')
{
state = seeking2;
}
break;
case seeking2:
if (ch == '/')
{
state = comment;
}
else
{
state = seeking1;
}
break;
case comment:
std::cout << ch;
break;
}
}
if (state == comment)
{
std::cout << std::endl;
}
}
return 0;
}
Why are these approaches all wrong? Consider the line
cout << "Hi there! I am \\Not A Comment!" << endl;`
You can't just look at the \\, you also need the context. This is why the state machine above is the better option. It can be modified to handle, at the very least, states for handling strings and block comments.

I am having an error with my for loop and can't figure out why, I have an "expected declaration" error

This is a program that tests for password strength. I used simple tests to check the password, but I am having issues. Let me state that I am not very good with c++, so sorry if the error is apparent
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <cctype>
using namespace std;
int main()
{
cout << "Please enter your password!" << endl;
cin >> password;
}
bool hasUpp = false;
bool hasLow = false;
bool hasDig = false;
bool hasSym = false;
string strlen, password; //The next line is throwing the error, expecting a declaration
for(int i = 0; < strlen(string1); ++i) //This is where my error is
{
if (isupper(string1[i]))
hasUpp = true;
if (islower(string1[i])) //Do all of these if statements seem correct?
hasLow = true;
if (isdigit(string1[i]))
hasDig = true;
if (issymbol(string1[i]))
hasSym = true;
if (strlen <= 7) //would this be the right way to check for string length?
return false;
if (strlen >= 8)
return true;
}
if (hasLow && hasUpp && hasDig && hasSym)
{
return true;
}
else
{
return false;
}
I am having issues with the for loop towards the top, I can not seem to get rid of this error. I don't know what else to write about it, I can't post this without adding more text though so I'm just going to write more words until it let's me post
You've put a bunch of statements (specificaly a for loop and an if statement) in global scope. Only declarations can appear there (althoug those can contain expressions).
To simplify your code:
int main()
{
cout << "Please enter your password!" << endl;
cin >> password;
} // the body of main ends here
for (;;) {} // this doesn't belong here
Once you fix that, there's another error:
for(int i = 0; < strlen(string1); ++i)
// ^^^^
// something's missing here
sorry to say but..there are all sorts of things missing in your code here is a more correct version.. try to check the differences.. still somethings may be missing.. but hopefully it puts you on the right track
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <cctype>
using namespace std;
int main()
{
string password; //must be declared before use
cout << "Please enter your password!" << endl;
cin >> password; //fetch password
int nlen = strlen(password); //collect the length of text
if (nlen <= 7) //no need to be done inside loop
return false;
if (nlen >= 8)
return true;
bool hasUpp = false;
bool hasLow = false;
bool hasDig = false;
bool hasSym = false;
for(int i = 0; i < nlen ; ++i) //proper iteration
{
if (isupper(password[i]))
hasUpp = true;
if (islower(password[i]))
hasLow = true;
if (isdigit(password[i]))
hasDig = true;
if (issymbol(password[i]))
hasSym = true;
}
if (hasLow && hasUpp && hasDig && hasSym)
{
return true;
}
else
{
return false;
}
}
In this line you declare 2 variables type string:
string strlen, password;
in this line you are trying to use variable strlen as a function and put there a variable string1 that does not exist:
for(int i = 0; < strlen(string1); ++i)
and you try to use string1 further in the code.
Looks like you copy paste code from somewhere without trying to understand what you are doing.
#include <iostream>
#include <string>
#include <cmath>
#include <iomanip>
#include <cctype>
using namespace std;
// Globals on top
bool hasUpp = false;
bool hasLow = false;
bool hasDig = false;
bool hasSym = false;
// Password Goes Here According to your code
string password;
int main() {
cout << "Please enter your password!" << endl;
cin >> password;
int stringlength = strlen(password);
// check string length here
for(int i = 0; i < stringlength; i++) { // As said, the i was missing, also normally you see i++ in code
if (isupper(string1[i]))
hasUpp = true;
if (islower(string1[i])) //Do all of these if statements seem correct? Yes
hasLow = true;
if (isdigit(string1[i]))
hasDig = true;
if (issymbol(string1[i]))
hasSym = true;
// dont check string length here
}
}
I updated your code, it may or may not compile, but I fixed the errors I saw.

how to print out more than a character at once

I saved this word "abs" in a text file and i'm trying to make a code that can print the three characters at once in another file .. not like that
while (content[i] == 'a')
{
fout<<"a";
break;}
while (content[i] == 'b')
{
fout<<"b";
break;}
while (content[i] == 's')
{
fout<<"s";
break;}
here is the code i wrote but it doesn't print anything out..
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ofstream fout("E:\\hoss.txt");
ifstream file("E:\\test.txt");
string content;
while(file >> content)
{
for (size_t i = 0; i < content.size(); i++)
{
while (content[i] == 'ab')
{
fout<<"ab";
break;}
}}
system("pause");
return 0;
}
anyone can help??
int main()
{
ofstream fout("E:\\hoss.txt");
ifstream file("E:\\test.txt");
string content;
while(file >> content)
{
for (size_t i = 0; i < content.size(); i++)
{
if((content[i] == 'a') && (content[i+1] == 'b'))
{
fout<<"ab";
break;
}
}
}
system("pause");
return 0;
}
You have no code to print anything out. You just keep adding to the buffer, but you never flush the buffer. Get rid of the system("pause"); and just let the program end. Ending the program flushes all buffers.
while (content[i] == 'ab')
This is pretty baffling. Did you really mean ab as a character constant?