Segmentation Fault Error for a simple program in main() function - c

I just started teaching myself C, and wanted to write a basic program in main() that would take user input for a password, check it with the correct password, and have an appropriate output. However, the program started running and it read user input, but then it suddenly terminated under the error Segmentation Fault (code dumped). What's wrong with the code that's causing the error?
#include <stdio.h>
int main(void)
{
printf("Enter the password\n");
char guess;
scanf(" %c", &guess);
char password[] = "Hello123";
int correct = 0;
while (correct != 1){
if(strncmp(password,guess)==0){
printf("Success! You have logged in with your password
%c\n",guess);
correct +=1;
}
else
{
printf("Incorrect password. Try again\n");
}
}
}

Hey I took a privilege of recoding your code
#include <stdio.h>
#include <string.h>
int main(void)
{
char *guess;
const char password[] = "Hello123";
int correct = 0;
while (correct != 1){
/*
* Include the input prompt inside while loop
*/
if (correct == 0){
printf("Enter the password\n");
scanf(" %s", guess);
}
if(strncmp(password,guess, 10)==0){ //strncmp accept 3 params, set length e.g 10
printf("Success! You have logged in with your password %s\n",guess);
correct = 1;
}
else
{
printf("Incorrect password. Try again\n");
correct = 0;
}
}
}

Related

gets vs fgets for overflow in program

i have the following c program. when i enter input as bytebyte it is giving the wrong input due to buffer overflow.
this is the program
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
// Use a struct to force local variable memory ordering
struct {
char buff[5];
char perf;
} localinfo;
localinfo.perf = 0;
if(strcmp(localinfo.perf, "byte")){
printf ("\n Wrong Password \n");
}
else {
printf ("\n wrong Password\n");
localinfo.perf = 1; // Set a flag denoting correct password
}
//IF password matches
// GIVE root or admin rights to user
if(localinfo.pass){
printf ("\n Congratulations! Root privileges given to the user!\n");
}
return 0;
}
The correct password is byte, if enter byte it works fine.
if i enter bytebyte due to bufferoverflow the pass is modified as 1. and user is getting admin privileges.
if enter bytebyte as input output is
wrong password
Simply never use gets function, It is dangerous and obsolete.
Use fgets instead
fgets(localinfo.buff, sizeof(localinfo.buff), stdin);
To be sure that the whole line was read check if the last character is '\n'. If not assume that something is wrong and wrong password was entered.
Try this
#include <stdio.h>
#include <string.h>
int main(void) {
struct {
char buff[10];
char pass;
}
localinfo;
localinfo.pass = 0;
printf("\n Enter the password:\n");
scanf("%[^\n]s", localinfo.buff);
if (strcmp(localinfo.buff, "byte")) {
printf("\n Wrong Password \n");
} else {
printf("\n Correct Password\n");
localinfo.pass = 1;
}
if (localinfo.pass) {
printf("\n Congratulations! Root privileges given to the user!\n");
}
return 0;
}

C Program suddenly exits after first input when using printf()

I tried this code but after entering the first input it exits. This code works fine though when the printf("hello world"); is commented out or deleted. The compiler doesn't explain anything and it doesn't show any error so I dont know the solution. What is the reason behind this?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdbool.h>
bool login(bool logStatus) // takes in loggedIn value
{
char correctUsername[16] = "admin";
char correctPassword[16] = "admin123";
char *inputUsername;
char *inputPassword;
int i, checkUsername, checkPassword;
printf("Enter your username : \n");
fgets(inputUsername, 16, stdin); /* Get user input for username */
inputUsername[strlen(inputUsername) - 1] = '\0';
// scanf("%s", &inputUsername);
printf("Enter your password : \n");
fgets(inputPassword, 16, stdin); /* Get user input for password */
inputPassword[strlen(inputPassword) - 1] = '\0';
// scanf("%s", &inputPassword);
/* Check username and password */
checkUsername = strcmp(correctUsername, inputUsername);
checkPassword = strcmp(correctPassword, inputPassword);
printf("%d %d", checkUsername, checkPassword);
if (checkUsername == 0 && checkPassword == 0)
{
printf("\n\nLogged In Successful");
logStatus = true;
return logStatus;
}
else
{
printf("\n\nIncorrect username or password\n");
printf("Enter any key to continue...");
getch();
system("cls");
}
}
int main()
{
int input;
int choice;
bool loggedIn = false;
printf("hello world");
login(loggedIn);
return 0;
}
inputUsername and inputPassword are uninitialized pointers. You then pass them to fgets which attempts to dereference those invalid pointers. Doing so invokes undefined behavior.
Make them arrays like the username/password you're checking against.
char inputUsername[16];
char inputPassword[16];

why my email checker in C is not working?(I use an ispunct to detect that there are # on the email or not, but it seems not working)

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;
}

Encryption in C using a Caesar Cipher

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.

Counting Number Of User Input in C Program

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;
}

Resources