I have been asked to create a program where I have to encrypt multiple pieces of information using a Caesar Cipher. I understand the concept behind it but what I'm having trouble visually is how to enter pieces of data within the function. For example, I have encrypted passwords saved in a file ("hrkk1" meaning "pass1" and so on). I have to create a cipher function to read the input from a scanf and strcmp so it matches what's in the file allowing the user to login.
Whats the best way to validate the user input and make "pass1" turn into "hrkk1" so it matches what's in the file and allows user login?
Thank you
This is the code I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <windows.h>
void checkValid(void);
void loginDetails(char username[5][6], char password[5][9]);
void encryption(char username[5][6], char password[5][9]);
int main(void)
{
FILE *EP;
FILE *UN;
char username[5][6];
char password [5][9], ch, key;
EP = fopen("encrypted_passwords.txt", "r");
fscanf(EP, "%s %s %s %s %s", password[0], password[1],
password[2], password[3], password[4]);
fclose(EP);
UN = fopen("username.txt", "r");
fscanf(UN, "%s %s %s %s %s", username[0], username[1], username[2],
username[3], username[4]);
fclose(UN);
printf("Welcome.");
loginDetails(username, password);
return 0;
}
void loginDetails(char username[5][6], char password[5][9])
{
int i;
char nurseUsername[6];
char nursePassword[6];
bool useValid = 0;
bool passValid = 0;
printf("Please Enter your username: \n");
scanf("%s", nurseUsername);
for (i = 0; i < 5; i++)
{
if(strcmp(nurseUsername, username[i]) == 0)
{
useValid = 1;
}
}
if(useValid != 1)
{
printf("\nError. Invalid Username. Returning to menu.\n");
Sleep(1000);
system("cls");
main();
}
else
{
printf("\nPlease enter your password: \n");
scanf("%s", nursePassword);
}
for(i = 0; i < 5; i++)
{
if((strcmp(nurseUsername, username[i]) == 0) &&
(strcmp(nursePassword, password[i]) == 0))
{
passValid = 1;
}
if(passValid != 1)
{
printf ("Error. Invalid Password. Returning to menu.\n");
Sleep(1000);
system("cls");
main();
}
else
{
printf("\nLogin Successful. Loading menu.\n");
Sleep(1000);
system("cls");
patientEntry();
}
}
}
You need to use the shifting of the character in c. This is possibile with a simple addition( or subtraction) on a char value.
Pay attention your example doesn't shift the number character and maybe also the character doesn't go out the alphabet, and it take in consideration also the capital letters. So pay attention when you do the addition to not exceed the range of capital or non capital letter. My suggestion is to use ascii table.
Related
I just recently starts learning C and found a problem. So here is my code:
#include <stdio.h>
#include <ctype.h>
int main()
{
char email[100];
int i;
printf("Input username (email) :");
scanf("%s", email);
for (i = 0; email[i] != '\0'; ++i)
{
if(!ispunct(email[i]))
{
printf("Please input a correct username (email) :");
scanf("%s", email);
}
}
return 0;
}
So, the program somehow only finished if I only input 1 character like # or other punctuation, but if I add alphabet like jack#gmail.com it will loop forever until I input only 1 punctuation. so can somebody please tell me whats wrong? I am trying to make a program that will only loop if I only input alphabet and didn't input punctuation like # or . in my email.
There are couple of suggestion:
use strchr() to find a particular charcater.
Loop over the same input instruction until you find a satisfactory input.
A modified version of your code can be
#include <stdio.h>
#include <string.h>
int main(void)
{
char email[100];
char toBeFound = '#'; // instead of any punctuation, make your search precise
while (1){ // go for a loop till the valid input is received.
printf("Input username (email) :\n");
scanf("%99s", email); //length limit the input, to avoid buffer overflow problem.
if (strchr (email, toBeFound)){ // search whether the required character is there
//in the input or not
printf ("%s is a valid email address\n", email);
break;
}
printf ("The input %s is not valid\n", email); // for debug, can be removed.
}
return 0;
}
Your program start the loop with i = 0 and test the first character in email. If this first character is not a punctuation, your program asks for a new email. So your program keeps testing only the first character and it requires that it’s a punctuation.
You should accumulate the result of the ispunct test and test the result.
#include <stdio.h>
#include <ctype.h>
int main()
{
char email[100];
int i;
printf("Input username (email) :");
scanf("%s", email);
for () {
int done = 0;
for (i = 0; email[i] != '\0'; ++i)
done |= ispunct(email[i]);
if (done != 0)
break;
printf("Please input a correct username (email) :");
scanf("%s", email);
}
return 0;
}
printf("Enter number of patients:");
int numberOfInputs = scanf("%d", &patients);
if (numberOfInputs != 1) {
printf("ERROR: Wrong number of arguments. Please enter one argument d.\n");
}
I am asking the user to input one number as an argument, but would like to print out a statement if the user does not input anything or puts in more than one input. For example, once prompted with "Enter number of patients:", if the user hits enter without entering anything, I would like to print out a statement. The code above is what I have been specifically tinkering around with it for the past couple hours as a few previous posts on this site have suggested but when I run it in terminal, it does not work. Any suggestions? Thank you in advance, and all advice is greatly appreciated!
If I understand your question right, you want to print an error when the input is anything other than an integer and this includes newline as well. You can do that using a char array and the %[] specifier.
Example:
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int patients;
char str[10];
printf("Enter number of patients:");
int numberOfInputs = scanf("%[0-9]", str);
if (numberOfInputs != 1) {
printf("ERROR: Wrong number of arguments. Please enter one argument.\n");
}
patients = atoi(str); //This is needed to convert the `str` back to an integer
}
This will print the error when the user just hits ENTER as well.
This looks super over-complicated, but it basically splits the input, checks it to be exactly one and than checks it to be an integer (and converts it). It works fine in loop as well and handles empty input.
I'm sure there are more elegant solutions to this problem, it's just a suggestion.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int getNumberOfInput(char* str);
bool isNumber(char* str);
int main()
{
char str[512];
while(1)
{
printf("Enter text: ");
fgets(str, 512, stdin);
int numberOfInput = getNumberOfInput(str);
if ( numberOfInput == 0 )
printf("You must give an input\n");
else if ( numberOfInput > 1 )
printf("You have to give exactly one input\n");
else
{
if (!isNumber(str))
printf("The input is not an integer\n");
else
{
int input = atoi(str);
printf("input: %d\n", input);
}
}
}
return 0;
}
int getNumberOfInput(char* str)
{
char* word = strtok(str, " \t\n\v\f\r");
int counter = 0;
while(word != NULL)
{
++counter;
word = strtok(NULL, " \t\n\v\f\r");
}
return counter;
}
bool isNumber(char* str)
{
int i, len = strlen(str);
for (i=0; i<len; ++i)
if (!isdigit(str[i]))
return false;
return true;
}
I'm working on something small and I have run into a really small but disturbing problem - the program works in gcc, but crashes in visual studio, when it gets to the fgets command:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void registerUser(char *username);
char path[256] = "C:\\Users\\magshimim\\Desktop\\cproject\\bank\\";
int main() {
int choice = 0;
char username[10];
printf("Welcome to nikitosik's bank program!\n"
"Choose an option :\n"
"0 - Register\n"
"1 - Login to existing account\n");
scanf("%d", &choice);
getchar(); // catch enter
if (!choice) {
registerUser(username);
} else {
//login();
}
}
void registerUser(char *username) { // username is passed, for verification later
FILE *userinfo; // file that contains info of all registered users
FILE *userpathf; // file to open for txt file
char usertxt[256]; // path of data
char userpath[256]; // path of new user data file
char password[15];
strcat(userpath, path);
strcat(usertxt, path);
strcat(usertxt, "users.txt");
userinfo = fopen(usertxt, "a");
printf("Choose a username(max 10 letters): ");
fgets(username, 10, stdin);
username[strcspn(username, "\n")] = 0;
strcat(userpath, username);
strcat(userpath, ".txt");
userpathf = fopen(userpath, "w");
fclose(userpathf);
printf("Choose a password(max 15 letters): ");
fgets(password, 15, stdin);
fprintf(userinfo, "%s\n%s", username, password);
fclose(userinfo);
}
thanks in advance
As above really or initialize the strings first.
memset(userpath, 0, sizeof(userpath));
memset(usertxt, 0, sizeof(usertxt));
Your program has multiple issues:
you concatenate a string into an uninitialized array: this has undefined behavior and may well explain the observed behavior on different systems as undefined behavior may take multiple forms from no consequence at all to a crash or possibly even worse misfortune.
you do not test the return values of scanf, fopen, fgets(). Any invalid or unexpected input may trigger more undefined behavior.
you do not check for potential buffer overflow in strcat(). You should instead use snprintf().
Here is a safer version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int registerUser(char *username, size_t size);
char path[] = "C:\\Users\\magshimim\\Desktop\\cproject\\bank\\";
int main(void) {
int choice = 0;
int c;
char username[10];
printf("Welcome to nikitosik's bank program!\n"
"Choose an option :\n"
"0 - Register\n"
"1 - Login to existing account\n");
if (scanf("%d", &choice) != 1)
return 1;
// consume the rest if the input line
while ((c = getchar()) != EOF && c != '\n')
continue;
if (choice == 0) {
registerUser(username, sizeof(username));
} else {
//login();
}
return 0;
}
int registerUser(char *username, size_t size) { // username is passed, for verification later
char usertxt[256]; // path of data
char userpath[256]; // path of new user data file
char password[17];
FILE *userinfo; // file that contains info of all registered users
FILE *userpathf; // file to open for txt file
printf("Choose a username(max %d letters): ", (int)(size - 2));
if (!fgets(username, size, stdin))
return -1;
username[strcspn(username, "\n")] = 0; // strip newline if any
printf("Choose a password(max 15 letters): ");
if (!fgets(password, sizeof(password), stdin))
return -1;
password[strcspn(password, "\n")] = 0; // strip newline if any
if (snprintf(usertxt, sizeof(usertxt), "%s%s", path, "users.txt") >= (int)sizeof(usertxt))
return -1;
if (snprintf(userpath, sizeof(userpath), "%s%s.txt", path, username) >= (int)sizeof(userpath))
return -1;
userinfo = fopen(usertxt, "a");
if (userinfo == NULL)
return -1;
// create user file
userpathf = fopen(userpath, "w");
if (userpathf != NULL)
fclose(userpathf);
// add user info
fprintf(userinfo, "%s\n%s\n", username, password);
fclose(userinfo);
return 0;
}
I am trying to build a program which will take in a list of login details (usernames and passwords) from a file and allow you the option to enter a username and password which are compared with the approved logins and a result is given. In my strcmp I am receiving access violation error 0xC0000005.
#include <stdio.h>
#include <conio.h>
#include<stdlib.h>
FILE *fptr;
void main();
void openFile();
void closeFile();
char approvedUsrnames[3][6];
char approvedPassword[3][6];
void main()
{
char userPassword[6], usrname[6], inputChar, fileString[6];
int i;
openFile();
int numofLogins= 3;
if (fptr != NULL)
{
printf("\nReading file with scanf\n");
while (!feof(fptr))
{
for (i = 0; i < 3; i++) {
fgets(approvedUsrnames[i], 6, fptr);
fgets(approvedPassword[i], 6, fptr);
}
}
closeFile();
}
printf("Enter User name: ");
scanf("%s",usrname);
printf("Enter the password <any 6 characters>: ");
for (i = 0; i<6; i++)
{
inputChar = _getch();
userPassword[i] = inputChar;
inputChar = '*';
printf("%c", inputChar);
}//obfuscate the input to the user
/*If you want to know what you have entered as password, to be removed*/
printf("\nYour password is %s:", userPassword);
for (i = 1; i < 3; i++) {
printf("\Username is good %s\n", approvedUsrnames[i]);
if (strcmp(approvedUsrnames[i], usrname == 0)){
printf("\Username is good\n");
if (strcmp(userPassword, approvedPassword[i]) == 0) {
printf("\nPassword is good\n");
}//end nested if
else {
printf("\nPassword is not match\n");
}
}//end if
}//end for
_getch();
}
void openFile()
{
fptr = fopen("approvedLogins.dat", "r");
if (fptr == NULL)
{
printf("Error opening file ! \n");
}
else {
printf("Login file read successfully ! \n");
}
}
void closeFile()
{
fclose(fptr);
}
#anthonygordon
It is very likely that the strings usrname and userPassword aren't being terminated with '\0' (null terminator) a) as the scanf() may attempt to fill in more chars than usrname can capture b) for loop has to iterate only 5 times so that userPassword[5] is to be explicitly set to '\0'. (If the expectation is to use 6 character long username and password, then change the length of array from 6 to 7 and make sure array[6] is filled with '\0') (Remember in 'C' array subscripts goes as 0..(arraysize-1))
Also, once the user name and password matches, break-out from the loop.
You picked specific lengths for your username and password character arrays. This means that you know the amount of characters you want to compare.
In such a case you do not need to add a '/0' to your character array. Simply use the strncmp() function and specify the number of characters to compare in the second parameter.
See: http://www.tutorialspoint.com/c_standard_library/c_function_strncmp.htm
Just a tip:
Test after every bit of code that you add. This way it is easy to know what code caused the problem. Only when you get really experienced (perhaps 4+ years of coding) can you be brave and write more code before testing.
I'm new to this forum and would like to seek help. I'm trying to modify an anagram program based on code from http://www.sanfoundry.com/c-program-...ings-anagrams/.
This time, however, I have used array pointers to obtain input from the user. I have also created a function "check_input" to ensure that the input consists of ONLY characters and excludes symbols(!, #, $). However, when I ran the program, it still accepts those symbols and does not break like I wanted it to. Please help.
Plus, I intend to make the program treat upper-case letters the same way as lower-case letters. Can this be achieved by using the "stricmp" function? If so, where should I place that function? Alternative methods are also appreciated.
Update: Sorry. I've added the check_input code at the bottom.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int test_anagram(char *ptrArray1, char *ptrArray2);
int check_input(char array1[], char array2[]);
int main()
{
char array1[100], array2[100];
char *pArray1, *pArray2;
int flag;
pArray1 = array1;
pArray2 = array2;
printf("Enter the first word: \n");
gets(pArray1);
printf("Enter the second word: \n");
gets(pArray2);
check_input(pArray1, pArray2);
flag = test_anagram(pArray1, pArray2);
if(flag == 1){
printf("\"%s\" and \"%s\" are anagrams.\n", pArray1, pArray2);
}else{
printf("\"%s\" and \"%s\" are not anagrams.\n", pArray1, pArray2);
}
return 0;
}
int test_anagram(char array1[], char array2[])
{
int num1[26] = {0}, num2[26] = {0}, i = 0;
while(array1[i] != '\0')
{
num1[array1[i] - 'a']++;
i++;
}
i = 0;
while(array2[i] != '\0')
{
num2[array2[i] - 'a']++;
i++;
}
for(i=0;i<26;i++)
{
if(num1[i] != num2[i]){
return 0;
}
return 1;
}
}
int check_input(char array1[], char array2[])
{
while(isalpha((int)array1) != 1){
break;
}
while(isalpha((int)array2) != 1){
break;
}
}
You haven't (yet) posted the full code of the check_input() function but one advice would be to validate the input when the user inputs every character.
You can do this using f.e. the getchar() function and checking if the inputted character is a letter, as well as converting it to the lowercase (or uppercase if you will).
You can do lowercase convertion like this:
#include <ctype.h>
// ...
tolower('A');