password verification or checker in c programming - c

I have created a password checker in c programming but it is not working can anyone please check it and say what is wrong in this.‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎
#include<stdio.h>
#include<stdbool.h>
int main() {
int otp[4]; //array for storing the true password entered by user at first
int pto[4]; //array for storing password for login
int count = 4,i;
bool pass = true;
printf("enter a new password: ");
for (int i = 0; i < count; i++) {
scanf("%d", & otp[i]); //for storing the true password
}
printf("\n\n --- Login page --- ");
printf("\nenter your password : ");
for (i = 0; i < count; i++) {
scanf(" %d", & pto[i]); //asking for password for login
}
for (i = 0; i < count; i++) { //check for password
if (otp[i] == pto[i]) {
pass = true;
} else {
pass = false;
}
}
while (pass == false) { //if password is wrong
printf("\n---- password din't match ----\nenter your password again : ");
for (i = 0; i < count; i++) {
scanf(" %d", & pto[i]);
}
for (i = 0; i < count; i++) {
if (otp[i] == pto[i]) {
pass = true;
} else {
pass = false;
}
}
}
printf("\n Your password is correct!");
return 0;
}
And should I use int or char to store passwords,if i use int also that part works if char also it works but sometimes it wont work,

This loop ultimately only cares if the last value in each array match or not.
for (i = 0; i < count; i++) {
if (otp[i] == pto[i]) {
pass = true;
} else {
pass = false;
}
}
For example, comparing { 1, 2, 3, 4 } and { 4, 4, 4, 4 } would result in pass being true after the loop, despite the obvious differences.
Instead, set the flag to false, and break from your loop as soon as a mismatch occurs.
bool matching = true;
for (size_t i = 0; i < length; i++) {
if (array_one[i] != array_two[i]) {
matching = false;
break;
}
}
If a mismatch never occurs, the flag will remain true afterwards.
Usually passwords are text that is hashed (with a salt) before being stored. Password verification is done by comparing hashes. For example, take a look at the man 3 crypt library function.
The use of a fixed-length series of plain integers for a 'password' is atypical, but for a toy program it is fine.
Here is an example program to study.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define KEY_LENGTH 4
void get_key(int *key, size_t length) {
for (size_t i = 0; i < length; i++) {
if (1 != scanf("%d", &key[i])) {
fprintf(stderr, "Could not read integer input.\n");
exit(EXIT_FAILURE);
}
}
}
bool match_key(int *one, int *two, size_t length) {
for (size_t i = 0; i < length; i++)
if (one[i] != two[i])
return false;
return true;
}
int main(void) {
int key[KEY_LENGTH];
int user_key[KEY_LENGTH];
printf("Set the key (%d integers): ", KEY_LENGTH);
get_key(key, KEY_LENGTH);
puts("--- LOGIN ---");
while (1) {
printf("Enter the key (%d integers): ", KEY_LENGTH);
get_key(user_key, KEY_LENGTH);
if (match_key(key, user_key, KEY_LENGTH))
break;
puts("Key mismatch. Retrying...");
}
puts("Welcome to the system.");
}

Since you didn’t specify your problem (besides “it’s not working”), I’ll do my best to list all the possible issues.
Reading integers
scanf("%d", & otp[i]);
Will read a single decimal integer into a position in otp. If the password is 1024, the first time through the loop (iteration) will read 1024 into otp[0]. In the second iteration, scanf() will wait until another number is available on standard input. Once it’s available, it will read it into otp[1], and so on. This scanf() loop really reads in 4 different integers, separated by newlines. It would be much easier to do only one scanf() for one integer, like this:
int main() {
int otp;
int pto;
bool pass = true;
printf("enter a new password: ");
scanf("%d", &otp);
You could also scan a 4-character string by using char arrays:
int main() {
char otp[5]; //4 digits and 1 NUL-terminator
char pto[5];
bool pass = true;
printf("enter a new password: ");
scanf("%4s", otp);
Password-checking logic error
As #Oka explained, your checker has a logic error. If using an integer, you could simply check
if (opt == pto) {
//correct
} else {
//incorrect
}
If using a char array (string), you could use
if (!strcmp(otp, pto)) {
//correct
} else {
//incorrect
}
You would have to #include <string.h> for strcmp().
Standard output buffer
The “enter a new password: ” prompt is not printed until the stdout buffer is flushed. This usually only happens when a newline is printed. You have to
fflush(stdout);
right after printing the prompt if you want it to appear.

Related

I am receiving the following error: expected identifier or '('

The error is referencing the following line of code:
tenant[i].name = get_string("Enter the residents name: ");
and has an arrow pointing at the period . between tenant[i] and name. I am not sure what I am missing.
typedef struct {
string name;
int apt;
} tenant;
int n;
int numres(void);
string nameres(int numres);
int apt(int numofres);
int main(void) {
int numres(void);
tenant tenants[n];
string nameres(int n);
int apt(int n);
for (int m = 0; m < n; m++) {
printf("Resident %s resides in apt# %i\n",
tenants[m].name, tenants[m].apt);
}
return 0;
}
//this function prompts the user for the number of residents
int numres(void) {
do {
n = get_int("Enter the number of residents: ");
} while (isalpha(n) != 0 || isspace(n) != 0);
return n;
}
// this function prompts the user for the residents names.
string nameres(int numres) {
int i = 0;
do {
tenant[i].name = get_string("Enter the residents name: ");
return tenant[i].name;
i++;
} while (i < numres);
}
// this function prompts the user for the residents apt number
int apt(int numofres) {
for (int i = 0; i < numofres; i++) {
tenant[i].apt = get_int("Enter residents apt number: ");
return tenant[i].apt;
}
}
There are multiple problems in the code:
the string type is not a standard C type, it is defined in <cs50.h> as a typedef for char *, which can be quite confusing. Make sure you include <cs50.h> and <stdio.h>.
in the main function, you define tenant tenants[n];, an array with a length specified by a variable that has a value of 0: this has undefined behavior, and the array cannot be used for anything.
in the main function, you declare functions int numres(void);, string nameres(int n); and int apt(int n);. Such declarations should be made at the file scope, and indeed are done so already. You probably meant to call the functions instead, so you should write:
int main(void) {
numres();
tenant tenants[n];
nameres(n);
apt(n);
for (int m = 0; m < n; m++) {
printf("Resident %s resides in apt# %i\n",
tenants[m].name, tenants[m].apt);
}
return 0;
}
But passing the value of n as a global variable is cumbersome and confusing. numres() should return the value and n should be a local variable.
in numres, it does not make sense to test isalpha(n) != 0 || isspace(n) != 0 because n is a number, not the value of a byte read from the input stream. The function get_int already checks for valid input and returns a converted number, you should just check that the number is positive: n > 0.
nameres should be defined as a void function and use a for loop for the case where n has the value 0.
in nameres and apt should receive tenants as an argument as this array is defined locally in main. The code should use tenants instead of tenant, which is a type name. This is the reason for your compilation issue. Using a _t suffix for the types is recommended to avoid such problems.
in nameres and apt should should prompt for the name and apartment numbers of all residents, remove the return statements.
using while or for loops instead of do / while loops allows for more concise code with explicit tests closer to the generating fact.
Here is a modified version:
#include <cs50.h>
#include <stdio.h>
typedef struct tenant_t {
string name;
int apt;
} tenant_t;
int numres(void);
void nameres(tenant_t tenants[], int numres);
void apt(tenant_t tenants[], int numres);
int main() {
int n = numres();
tenant_t tenants[n];
nameres(tenants, n);
apt(tenants, n);
for (int i = 0; i < n; i++) {
printf("Resident %s resides in apt# %i\n",
tenants[i].name, tenants[i].apt);
}
return 0;
}
// this function prompts the user for the number of residents
// it returns the number which must be strictly positive
int numres(void) {
for (;;) {
int n = get_int("Enter the number of residents: ");
if (n > 0)
return n;
}
}
// this function prompts the user for the residents names.
void nameres(tenant_t tenants[], int numres) {
for (int i = 0; i < numres; i++) {
tenants[i].name = get_string("Enter the residents name: ");
}
}
// this function prompts the user for the residents apt number
void apt(tenant_t tenants[], int numres) {
for (int i = 0; i < numres; i++) {
tenants[i].apt = get_int("Enter residents apt number: ");
}
}

Whenever i run the following code i get 'great password' as output irrespective of the input

This program asks the user for a password. It requires to test whether their password has an uppercase letter, lowercase letter, and a digit. If it does, the program says the great password. If not, it says choose another password.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void) {
// This part takes input from the user
int i;
int hasupper, haslower, hasdigit;
char password[20];
printf("eneter a password not more then eight characters long: \n");
scanf("%s", password);
// This part executes the loop to check the elements of the input.
for (i = 0; i < strlen(password); i++) {
if (isupper(password[i])) {
hasupper = 1;
continue;
}
if (islower(password[i])) {
haslower = 1;
continue;
}
if (isdigit(password[i])) {
hasdigit = 1;
}
}
// This part shows the outcome
if ((hasdigit) && (haslower) && (hasupper)) {
printf("great password\n");
} else {
printf("choose another password please\n");
}
}
Now, whenever I run my program I see great password on the screen as output for whatever input I give.
Your helper variables are uninitialized and therefore untrustworthy (besides causing UB)
// int hasupper, haslower, hasdigit;
int hasupper = 0, haslower = 0, hasdigit = 0;

First 2 elements of an array don't show in output after for loop

#include<stdio.h>
#include<string.h>
int main()
{
char cleartxt[256];
printf("what do you want to cipher? (lower cases only)\n");
fgets(cleartxt, sizeof(cleartxt), stdin);
int len = strlen(cleartxt);
unsigned short method;
printf("do you want to use method 1 (Caesar's cipher) or method 2(scrambled alphabet)?\n");
scanf ("%d",&method);
if (method==1) {
int key;
printf("what's your key?\n");
scanf("%d",&key);
for (int i=0; i < (len - 1); i++) {
if (cleartxt[i]<=122) {
if (cleartxt[i]>=97)
cleartxt[i] = 97 + (((cleartxt[i]%97)+key)%26);
printf ("%c", cleartxt[i]);
} else {
printf("%c",cleartxt[i]);
}
}
} else printf("the number is invalid");
return 0;
}
I was testing the first part of this program to see if it worked so far, but in output the first 2 elements of the array are skipped.
If i remove the if to decide the method, the for loop works just fine and i can't understand why

Find a string that matches another string on specific position, ignore other strings (C strings)

Let's say I have an array of phone numbers: char numbers[4][9] = {"555555534", "112221222", "512221222", "355555534"}; I need to find there phone numbers, that matches a specific pattern.
For example, I can find a number:
5******** that starts with a 5, and the rest of the digits can be ignored (does not matter what they're really)
**2***** the third digit is 2, and the rest of the digits can be ignored (does not matter what they're really)
etc.
The pattern I should look for is given by the user. I wrote a simple test, but somehow I have problems with implementing the number_matches function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i,j;
char *findmeplz = "5********";
char numbers[4][9] = {"555555534", "112221222", "512221222", "355555534"};
for (i=0; i<4; i++)
{
if(number_matches(numbers[i], findmeplz))
{
printf("number found on position %d\n", i);
break;
}
}
return 0;
}
The function can be like the following:
int number_matches(char* number, char* pattern)
{
int i = 0, flag = 1;
for(i = 0; i < strlen(pattern); i++)
{
if(pattern[i] != '*')
{
if(pattern[i] != number[i])
{
flag = 0;
break;
}
}
}
return flag;
}

I can not input the names into the char array using scanf

I can not use scanf to enter a name in stdnames array.
when compiled it had no error , but as soon as i enter a name and
then press enter to write the other name it gives an error and shuts the program.
How should I go about it ?
int main(int argc, char* argv[])
{
float marks[50];
/*char *stdnames[100]={"Arvind Thillainathan","Robert Lang"};*/
//I want to stores names like the above one
char *stdnames[100];
int totalNames = 0;
int i = 0, w=0,h=0;
printf("How many names do you want to enter ??\n");
scanf("%d",&totalNames);
assert(totalNames != 0);
for(int count = 0; count < totalNames; count++)
{
printf("Enter name of student\n");
scanf("%s",stdnames[count]);
//From here the problem starts
}
getres(marks,totalNames);
for(i = 0; i < totalNames; i++)
{
int v = 1;
printf("\n");
printf("IELTS Marks of %s\n\n",stdnames[i]);
for(h = w; h < w+5; h++)
{
if(v==1)
{
printf("Listening : %0.1f\n", marks[h]);
}
else if(v==2)
{
printf("Reading : %0.1f\n", marks[h]);
}
else if(v==3)
{
printf("Writing : %0.1f\n", marks[h]);
}
else if(v==4)
{
printf("Speaking : %0.1f\n", marks[h]);
}
else
{
printf("Overall : %0.1f\n\n", marks[h]);
}
v++;
//if(h==10)
//{
// break;
//}
}
w+=5;
}
return 0;
}
By
char *stdnames[100];
you got an array of (pointers to char).
The NEXT BIG QUESTION is
Who will allocate memory for each of these pointers?
A small answer would be - You have to do it yourself like below :
stdnames[count]=malloc(100*sizeof(char)); // You may replace 100 with desired size
or
stdnames[count]=malloc(100); // sizeof(char) is almost always 1
You need to put this line before the scanf statement.
Note: Don't forget to free the allocated memory once these variables become irrelevant. Do it like :
free(stdnames[count]);

Resources