We have a project that simulate the function of an atm. the user must enter a pincode and it will be masked with an asterisk. the input pincode must be equal to the default pincode that is stored in an array. My program can masked the input pincode with an asterisks, the only problem is that even if the input pincode is the same with the default pincode, it still output incorrect. what must be the problem? here is my code:
void checkPword()
{
char defaultPin[4] = "1234";
char inputPin[4] = "";
clrscr();
for (int cnt = 0; cnt <= 3; cnt++)
{
cout << "*";
inputPin[ctr];
}
if (defaultPin[0] == inputPin[0] && defaultPin[1] == inputPin[1]
&& defaultPin[2] == inputPin[2] && defaultPin[3] == inputPin[3])
{
clrscr();
cout << "pincode is correct";
}
else
{
clrscr();
cout << "pincode is incorrect";
}
}
Maybe you have to assign getch() to ctr?
ctr = getch();
Inside for..
PLUS: the instruction
inputPin[ctr];
does not have effects!
You have add:
inputPin[cnt] = putchar(ctr);
SUGGESTION
just to make code clear, replace "cnt" with "i".
SOLUTION
char defaultPin[4]="1234";
char input[4] = "";
char currentChar;
bool pinFail = false;
for(int i=0; i != 3; i++) {
currentChar = getchar();
input[i] = currentChar;
/* In this way you have only 3 if-control, not 3*4 as in your program */
if(currentChar != defaultPin[i]) {
pinFail = true;
}
}
if(pinFail) {
/* do something (print error?) */
} else {
/* coutinue with your application */
}
void checkPword()
{
char defaultPin[4]={1,2,3,4};
char inputPin[4]="";
clrscr();
for(int cnt=0;cnt<=3;cnt++)
{
inputPin[cnt] = getch();
cout<<"*";
}
if ((defaultPin[0]==inputPin[0])&&(defaultPin[1]==inputPin[1])&&(defaultPin[2]==inputPin[2])&&(defaultPin[3]==inputPin[3]))
{
clrscr();
cout<<"pincode is correct";
}
else
{
clrscr();
cout<<"pincode is incorrect";
}
}
Related
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
So writing a palindrome with pointers and boolean. I have it working with a single word but then I began building it to work with a sentence. The problem is I am unsure how to keep the new modified sentence after making it lowercase and getting rid of the spaces for it to return whether it is or isn't a palindrome. It keeps returning the palindrome as false and when I went to check why I see that the program ignores the modification and kept the original string. I can't use "&" on the parameter as I tested it out. Any hints or takes on what I can do to keep the new modified string?
int main()
{
userInput();
return 0;
}
void userInput()
{
char str[90];
std::cout<<"Please enter a string to check if it is a palindrome: ";
std::cin.getline(str, 90);
modifyString(str);
}
void modifyString(char *string)
{
int count = 0;
for (int i=0; i<strlen(string); i++)
{
putchar(tolower(string[i]));
}
for (int i = 0; string[i]; i++)
{
if (string[i] != ' ')
{
string[count++] = string[i];
}
}
string[count] = '\0';
std::cout<<string<<std::endl;
results(string);
}
bool checkPalindrome(char *string)
{
char *begin;
char *end;
begin = string;
end = (string + strlen(string)-1);
while(begin != end)
{
if ((*begin) == (*end))
{
begin ++;
end--;
}
else
{
return false;
}
}
return true;
}
void results(char *string)
{
bool isItPalindrome;
isItPalindrome = checkPalindrome(string);
if( isItPalindrome == true)
{
std::cout<<"\nCongrats, the string is a palindrome!";
}
else
{
std::cout<<"\nThis string is not a palindrome.";
}
}
For starters this definition of main
int main()
{
userInput();
return 0;
}
does not make a sense. According to the function name main the function should perform the main task that is to output whether the entered sentence is a palindrome or not.
This for loop
for (int i=0; i<strlen(string); i++)
{
putchar(tolower(string[i]));
}
does nothing useful. It just outputs the string in the lower case.
This statement
end = (string + strlen(string)-1);
can invoke undefined behavior if an empty string was passed.
This while loop
while(begin != end)
{
if ((*begin) == (*end))
{
begin ++;
end--;
}
else
{
return false;
}
}
also can invoke undefined behavior for a string containing an even number ofo characters because after this if statement
if ((*begin) == (*end))
{
begin ++;
end--;
}
if the two adjacent characters are equal then begin after incrementing will be greater than end after its decrementing. And as a result the loop will continue its iteration.
In general the approach when the original string is changed is just a bad approach.
Your program has too many functions. It is enough to write one function that will determine whether the passed string is a palindrome or not.
Here is a demonstrative program.
#include <iostream>
#include <cstring>
#include <cctype>
bool checkPalindrome( const char *s )
{
const char *t = s + std::strlen( s );
do
{
while ( s != t && std::isspace( ( unsigned char )*s ) ) ++ s;
while ( s != t && std::isspace( ( unsigned char )*--t ) );
} while ( s != t &&
std::tolower( ( unsigned char )*s ) == tolower( ( unsigned char ) *t ) &&
++s != t );
return s == t;
}
int main()
{
const size_t N = 100;
char s[N] = "";
std::cout << "Please enter a string to check if it is a palindrome: ";
std::cin.getline( s, N );
std::cout << '\n';
if ( checkPalindrome( s ) )
{
std::cout << "Congrats, the string is a palindrome!\n";
}
else
{
std::cout << "This string is not a palindrome.\n";
}
return 0;
}
Its output might look like
Please enter a string to check if it is a palindrome: 1 23 456 6 54 321
Congrats, the string is a palindrome!
Okay, I solved it!
As one of the users on here brought up a point that my lowercase did not modify the string and only prints it out. I try my best to solve the problem and I think I found the solution and everything works perfectly fine. comment back to debug it if you like to see how it looks but what I did was create a for loop again for the lower case but made another pointer with it. here how it looks.
for (char *pt = string; *pt != '\0'; ++pt)
{
*pt = std::tolower(*pt);
++pt;
}
Now that definitely changes the string into a lower case and keeps it as a lower case.
so now the modified function looks like this and ready to take any sentence palindrome you give it. Example: A nUt fOr a jAr of tUNa. We make this all lowercase and take out space and boom palindrome and return true.
void modifyString(char *string)
{
int count = 0;
for (char *pt = string; *pt != '\0'; ++pt)
{
*pt = std::tolower(*pt);
++pt;
}
for (int i = 0; string[i]; i++)
{
if (string[i] != ' ')
{
string[count++] = string[i];
}
}
string[count] = '\0';
//take out the forward slash below to see how it looks after being modified
// std::cout<<std::endl<<string<<std::endl;
results(string);
}
for my csc 102 class I have to create a program that will replace certain letters with others in a text file. The file holds five words and I have to use a class system. This sounds simple enough to me, but my variables in the class have to be pointer variables. Being that all of my classes are online now, trying to use my professors handwritten notes on canvas is all I have to explain how he wants projects done. I sort of understand what a pointer is. The pointer holds the address of a value. You have to dereference it with * to get the value stored there. However, I just don't see how pointers are to be used in this problem. This is the first prompt out of four and I just don't get what i'm supposed to do with the pointers. I will attach my code below and what the prompt asks me to do. I appreciate any help.
Prompt:
Problem 1: A computer keyboard has defect (like speech defect in humans) in reading for ‘p’ /’P’ as ‘f’/’F’ or vice versa and ‘n’/’N’ as ‘l’/’L’ or vice versa
Create a class with pointer variables that would correct the spelling of each word from the input.txt print them in in an output.txt.
Class Header file:
#pragma once
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class keyfix
{
char* input;
char* output;
string* word;
char* wordarray[10];
public:
keyfix();
~keyfix();
void readfile(ifstream&);
void correctspelling(ofstream&);
void outputfile();
void print()const;
};
class implementation file:
#include "keyfix.h"
keyfix::keyfix() {
input = new char;
output = new char;
*input = 'o';
*output = 'o';
word = new string;
*word = "empty";
*wordarray = new char;
}
keyfix::~keyfix() {
delete input;
delete output;
delete word;
input = output = NULL;
word = NULL;
}
void keyfix::readfile(ifstream& a) {
for (int i = 0; i < 10; i++) {
a >> wordarray[i];
}
}
I have an ifstream object and an ofstream object in main.
In my mind, I planned to use a character array instead of a string so that I could change each incorrect letter without using functions we haven't yet covered like anything in <algorithms>. I am in real need of some direction here. I am sure some of y'all can look at my code and tell, but I get a nullptr error whenever I try to test the read file function.
EDIT: I am now writing it with wordarray as a plain char array. It may be accepted this way, it may not be.
Also, the size is 10 because the file is provided and the largest word only has 10 letters.
As recommended in the comments, I wrote the program without pointers, and then changed a variable to a pointer type in my class. Here is the final project for any future students who happen to have this exact problem. (I saw the problem on chegg so I know he uses it commonly)
#pragma once
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class keyfix
{
char* input;
char wordarray[10];
public:
keyfix();
~keyfix();
void readfile(ifstream&);
void correctspelling(ofstream&);
void print()const;
};
#include "keyfix.h"
keyfix::keyfix() {
input = new char;
*input = 'o';
wordarray[10];
}
keyfix::~keyfix() {
delete input;
input = NULL;
}
void keyfix::readfile(ifstream& a) {
for (int i = 0; i < 10; i++) {
wordarray[i] = NULL;
}
a >> wordarray;
}
void keyfix::correctspelling(ofstream& b) {
for (int index = 0; index < 10; index++) {
*input = wordarray[index];
if (*input == 'f') {
wordarray[index] = 'p';
}
else if (*input == 'F') {
wordarray[index] = 'P';
}
else if (*input == 'p') {
wordarray[index] = 'f';
}
else if (*input == 'P') {
wordarray[index] = 'F';
}
else if (*input == 'n') {
wordarray[index] = 'l';
}
else if (*input == 'N') {
wordarray[index] = 'L';
}
else if (*input == 'l') {
wordarray[index] = 'n';
}
else if (*input == 'L') {
wordarray[index] = 'N';
}
b << wordarray[index];
}
b << endl;
}
void keyfix::print()const {
for (int i = 0; i < 10; i++) {
cout << wordarray[i];
}
cout << endl;
}
#include"keyfix.h"
//if input is f or F, output p or P
//if input is n or N, output l or L
//if input is p or P, output f or F
//if input is l or L, output n or N
int main() {
ifstream infile;
infile.open("input.txt");
ofstream outfile;
outfile.open("output.txt");
keyfix object;
for (int i = 0; i < 5; i++) {
object.readfile(infile);
object.correctspelling(outfile);
object.print();
}
}
For a project, we have to make a Caesar Cipher using classes and save the encrypted message inside of a file so a user can decipher it with the program.
I input the message and it has no problem encrypting the message according to the displacement/key I input (since I gave an option for the user to place the displacement they please).
However, the problem lies in decripting the message. It seems to only decript the penultimate or last letter of what I inputted and it doesnt even bother to show the remaining characters of the message.
I have currently no idea why its acting the way it is, I figured I would have to change the message to take char variables instead of string, but that would mean rewriting a large chunk of the code, and at the moment, I would like to avoid having to rewrite the code from scratch. If there are no other options, then I guess I will have to rewrite the code.
Here is the code, (hope that helps and sorry if my message may seem messy, this is the first time I post anything here):
#include<iostream>
#include<string>
#include<fstream>
#include<ctime>
#include<cstdlib>
/* This is a program that will grab a message from the user and encrypt it, then decrypt it
It will also generate a random 8-digit character password used to access the encrypted file
It will also have the ability to allow the user to choose how many spaces the cipher will take into account */
using namespace std;
//Implement a set displacement and get displacement
class Cipherer
{
private:
int displacement;
string message;
//string decryptMessage;
public:
void setDisplacer(int key);
int getDisplacer()const;
void msgEncripter(string, int);
string getMessage()const;
void msgDecripter(string);
string getDecription()const;
};
void Cipherer::setDisplacer(int key)
{
displacement = key;
}
int Cipherer::getDisplacer()const
{
return displacement;
}
void Cipherer::msgEncripter(string msg, int key)
{
string encriptedMsg = msg;
//.size returns the number of elements
for (unsigned int i = 0; i < msg.size(); i++)
{
if (msg[i] == 32) //32 is the value in ASCII of the space character
{
continue;
}
else
{
if ((msg[i] + key) > 122)
{
int temp = (msg[i] + key) - 122;
encriptedMsg[i] = 96 + temp;
}
else if (msg[i] + key > 90 && msg[i] <= 96)
{
int temp = (msg[i] + key) - 90;
encriptedMsg[i] = 64 + temp;
}
else
{
encriptedMsg[i] += key;
}
}
}
message = encriptedMsg;
}
string Cipherer::getMessage()const
{
return message;
}
void Cipherer::msgDecripter(string msg)
{
string decriptedMsg;
for (unsigned int i = 0; i < msg.size(); i++)
{
if (msg[i] == 32)
{
continue;
}
else
{
if ((msg[i] - displacement) < 97 && (msg[i] - displacement) > 90)
{
decriptedMsg[i] = (msg[i] - displacement) + 26;
}
else if ((msg[i] - displacement) < 65)
{
decriptedMsg[i] = (msg[i] - displacement) + 26;
}
else
{
decriptedMsg = msg[i] - displacement;
}
}
}
message = decriptedMsg;
}
string Cipherer::getDecription()const
{
return message;
}
static const char PASSWORD_POOL[] =
"0123456789";
int poolSize = sizeof(PASSWORD_POOL) - 1;
char getRandChar()
{
return PASSWORD_POOL[rand() % poolSize];
}
int main()
{
srand(time(0));
string pass, input, msg;
int key;
Cipherer message;
ofstream outputFile;
ifstream inputFile;
outputFile.open("SecretMSG.txt");
cout << "Write a message: \n";
getline(cin, msg);
cout << "Choose the displacement of the message (0-25): ";
cin >> key;
message.setDisplacer(key);
message.msgEncripter(msg, key);
outputFile << msg;
outputFile.close();
for (int count = 0; count < 1; count++)
{
for (int i = 0; i <= 7; i++)
{
pass += getRandChar();
}
cout << pass << endl;
}
cout << "Input password " << pass << " ";
cin >> input;
if (input == pass)
{
//Make a local variable to read file
string encryptedMessage;
inputFile.open("SecretMSG.txt");
inputFile >> encryptedMessage;
inputFile.close();
cout << message.getMessage() << endl;
cout << "If you wish to decrypt the message, type in the password once again " << pass << ": ";
cin >> input;
if (input == pass)
{
message.msgDecripter(encryptedMessage);
cout << message.getDecription() << endl;
}
else
{
exit(EXIT_FAILURE);
}
}
else
{
exit(EXIT_FAILURE);
}
system("pause");
return 0;
}
In msgDecripter your string decriptedMsg creates a string with the size 0, so any decriptedMsg[i] = is undefined behavior.
In your msgEncripter you write string encriptedMsg = msg;, and because you create a copy of mgs the encriptedMsg has the same size.
So either you do string decriptedMsg = msg or string decriptedMsg = std::string(msg.size(), ' ');
But a more c++ like approach would be to use transform.
string encriptedMsg = msg;
std::transform(encriptedMsg.begin(), encriptedMsg.end(), encriptedMsg.begin(),
[](unsigned char c) -> unsigned char {
if( c == ' ') {
return c;
} else {
// ... your other encrypting logic ...
}
});
Or using msg as source and an empty string as target and utilize std::back_inserter.
I have a delete function that is supposed to delete a string in an array by writing over it with the previous strings.
The look function see's that Overide matches and should be deleted. But the code i wrote for the loop in Delete is not removing that first spot in the array that Overide has taken up, and the output remains unchanged.
Also each phrase after + is being added into the array so four spots are taken in the array, and sorry i could not make that part look better the formatting screwed it up.
int AR::Look(const std::string & word)
{
int result = -1;
for(int i=0; i<counter; ++i)
{
if( con[i].find(word) != std::string::npos)
result = i;
}
return result;
}
void AR::Delete(const string & word)
{
int loc = Look(word);
if (loc == -1)
{
cout<<"word not found\n";
}
else
{
for(int i=0; i<counter-1,i++;)
{
con[i]= con[i+1];
}
}
}
AR their
Ar(1);
theirAr + "Overload the +" + " operator as a member function " + "with chaining to add a string " + "to an Arrary object.";
cout<<theirAr<<endl<<endl;
cout<<"testing Delete and Look. <<endl;
theirAr.Delete("XXXXXX");
theirAr.Delete("Overload");
cout<<"Output after Delete and Look called\n";
cout<<theirArray<<endl<<endl;
You are locating the String but only use the value to write an error if it does not appear; if you find the string at pos N you will delete the first string anyway:
void AR::Delete(const string & word)
{
int loc = Look(word);
if (loc == -1)
{
cout<<"word not found\n";
}
else
{
for(int i=0;i<counter-1,i++;) <--- Why don't you use loc here???
{
con[i]= con[i+1];
}
}
}
Also, your Look method would be better returning after the first match:
for ... {
if( con[i].find(word) != std::string::npos)
return i;
}
return -1;
Not sure if this is your problem, but shouldn't this be like so?
void AR::Delete(const string & word)
{
int loc = Look(word);
if (loc == -1)
{
cout<<"word not found\n";
}
else
{
for(int i=loc;i<counter-1,i++;) // changes in this line
{
con[i]= con[i+1];
}
}
}
Start at where you found the string and start shuffling them backwards. Also, what shortens the array? i.e. drops the last element off. Looks like that is missing too.
Try this instead:
int AR::Look(const std::string & word)
{
for (int i = 0; i < counter; ++i)
{
if (con[i].find(word) != std::string::npos)
return i;
}
return -1;
}
void AR::Delete(const string & word)
{
int loc = Look(word);
if (loc == -1)
{
cout << "word not found" << endl;
}
else
{
for (int i = loc+1; i < counter; ++i)
{
con[i-1] = con[i];
}
--counter;
}
}