getchar() skip the first character when tried to scan the input - c

I'm trying to scan the input from terminal and I'm trying to scan the initial white space but the program just skip it. I tried using this method before in a different program but it doesn't work in my new one. Plz help!!!
#include <stdio.h>
#include <string.h>
#define ADMIN_PASS "ABC123"
#define MAX_ARR_LEN 20
#define debug
void getinput(char inp[], int n);
void password(char passUser[]);
int main(void)
{
char passUser[MAX_ARR_LEN+1];
int i=1;
while (i==1)
{
password(passUser);
printf("Try again?(1/0)>");
scanf("%d",&i);
if (i == 1)
printf("\n");
}
return 0;
}
void getinput(char inp[], int n)
{
scanf("%[^\n]c", &inp[n-1]);
#ifdef debug
printf("\nThe entered code in function>%s\n",inp);
printf("The 1st character of entered code in function>%c\n",inp[0]);
#endif
}
void password(char passUser[])
{
char admin[MAX_ARR_LEN+1] = ADMIN_PASS;
do
{
printf("\nPlease enter the Administrator password to Login:\n");
getchar();
getinput(passUser);
#ifdef debug
printf("\nThe input password in main is>%s\n", passUser);
printf("The 1st character in main is>%c\n", passUser[0]);
#endif
if (strcmp(passUser, admin) != 0)
{
printf("The password entered is incorrect, try again\n");
}
} while (!(strcmp(passUser, admin) == 0));
}

You should pass the string with fgets(inp, sizeof(ADMIN_PASS), stdin) like this:
#include <stdio.h>
#include <string.h>
#define ADMIN_PASS "ABC123"
#define MAX_ARR_LEN 20
#define debug
void getinput(char * inp);
void password(char * passUser);
int main(void)
{
char passUser[MAX_ARR_LEN+1];
int i=1;
while (i==1)
{
password(passUser);
printf("Try again?(1/0)>");
scanf("%d",&i);
if (i == 1)
printf("\n");
}
return 0;
}
void getinput(char * inp)
{
fgets(inp, sizeof(ADMIN_PASS), stdin);
#ifdef debug
printf("\nThe entered code in function>%s\n",inp);
printf("The 1st character of entered code in function>%c\n",inp[0]);
#endif
}
void password(char * passUser)
{
char admin[MAX_ARR_LEN+1] = ADMIN_PASS;
do
{
printf("\nPlease enter the Administrator password to Login:\n");
getinput(passUser);
#ifdef debug
printf("\nThe input password in main is>%s\n", passUser);
printf("The 1st character in main is>%c\n", passUser[0]);
#endif
if (strcmp(passUser, admin) != 0)
{
printf("The password entered is incorrect, try again\n");
}
} while (!(strcmp(passUser, admin) == 0));
}
I removed getchar() and the second parameter of the function getinput() cause they were useless.

Related

Program is getting crashed when using getch and getche

#include <stdio.h>
#include <conio.h>
#define max 100
void compare(char *name,char* input);
int main()
{
int i=0;
char name[max]="santosh";
char input[max];
printf("enter the password\n");
while((input[i]=getchar())!='\n'){
i++;
}
input[i]='\0';
compare(name,input);
return 0;
}
void compare(char *name,char* input){
while((*name==*input)&&(*name!='\0'&&*input != '\0')){
*name++;
*input++;
}
if(*name=='\0'&&*input=='\0')
printf("Correct Password");
else
printf("Incorrect Password");
}
This Program is getting crashed in vs code but when I use getchar() instead of getch() or getche() all is working fine.
Why it is not working with getch() and how it will run as I want user to insert a password and thus want to use getch() not getchar().
First of all #define max generates a warning "macro redefinition", so change that.
The second problem is that getch() and getche do not convert the Enter key to 'newline' \n but to 'return' \r
The third problem is that instead of incrementing the pointers, you are incrementing what they point to.
Here is the corrected code:
#include <stdio.h>
#include <conio.h>
#define MAXX 100 // fixed macro name collision
void compare(char *name, char* input);
int main(void) // corrected definition
{
int i = 0;
char name[MAXX] = "santosh";
char input[MAXX];
printf("enter the password\n");
while((input[i] = getche()) != '\r') { // fixed '\n' check
i++;
}
input[i] = '\0';
compare(name, input);
return 0;
}
void compare(char *name,char* input){
while(*name == *input && *name != '\0' && *input != '\0') {
name++; // fixed pointer increment
input++; // fixed pointer increment
}
if(*name == '\0' && *input == '\0')
printf("Correct Password\n");
else
printf("Incorrect Password\n");
}
Finally you should also check i does not exceed the array bounds. The strings seem long enough, but not for players who try to break the program.

How to store a string that the user inputted into a char pointer instead of a char array

I'm trying to build a program with C but I'm having trouble changing a char array into a char pointer and adjusting the program accordingly. Here's my current code that I want to change:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
char username[20];
char password[20];
char username_input[20];
char password_input[20];
char user_input;
void create_account(char* usrname, char* passwd) {
printf("==================================CREATE BANK ACCOUNT==================================\n");
while(1) {
printf("Enter a username that is less than 20 characters: ");
scanf("%s", usrname);
if (strlen(usrname) <= 20)
break;
printf("That is not less than 20 characters, try again...\n");
sleep(2);
}
while(1) {
printf("Enter a password that is less than 20 characters: ");
scanf("%s", passwd);
if (strlen(passwd) <= 20) {
break;
}
printf("That is not less than 20 characters, try again... \n");
sleep(2);
}
printf("Thank you, please sign in now...\n");
sleep(2);
}
void login() {
while(1) {
printf("Enter Username: ");
scanf("%s", username_input);
printf("Enter Password: ");
scanf("%s", password_input);
if (strcmp(username, username_input) != 0 || strcmp(password, password_input) != 0) {
printf("Incorrect Username or Password. Try again...\n");
sleep(2);
}
else {
printf("Welcome %s\n", username);
sleep(2);
break;
}
}
}
On the lines at the beginning, you can see that there are 4 char array declarations. I want them to be char pointers like so:
char* username;
char* password;
char* username_input;
char* password_input;
The reason for this is because I don't want a limit in a string, but arrays need limits. Once I change that, I want to use malloc() to allocate memory for what the user inputs but I don't know how. In other words, I want to declare a char pointer that accepts user input. And I want enough memory to be allocated for that pointer so that the string that was inputted has enough space. Also I want my code to be compatible with different compilers and computers. For that I'm pretty sure that I have to multiply the malloc() function with sizeof(char) or something like that. I don't necessarily get an error, as in I don't get red lines in my IDE, but the program stops in the middle of it for no reason and gives me an exit code other than 0.
I have done something like this to alloc memory:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
void create_account(char** usrname, char** passwd);
void login(char** usrname, char** passwd, char** input_usrname, char** input_passwd);
void AllocMemory(char*** buf);
int main(){
char* username;
char* password;
char* username_input;
char* password_input;
create_account(&username, &password);
login(&username, &password, &username_input, &password_input);
free(username);
free(password);
free(username_input);
free(password_input);
return 0;
}
void create_account(char** usrname, char** passwd) {
printf("==================================CREATE BANK ACCOUNT==================================\n");
printf("Enter a Username: ");
AllocMemory(&usrname);
printf("Enter a Password: ");
AllocMemory(&passwd);
printf("Thank you, please sign in now...\n");
sleep(2);
}
void login(char** usrname, char** passwd, char** input_usrname, char** input_passwd) {
while(1) {
printf("Enter Username: ");
AllocMemory(&input_usrname);
printf("Enter Password: ");
AllocMemory(&input_passwd);
if (strcmp(*usrname, *input_usrname) != 0 || strcmp(*passwd, *input_passwd) != 0) {
printf("Incorrect Username or Password. Try again...\n");
sleep(2);
}
else {
printf("Welcome %s\n", *usrname);
sleep(2);
break;
}
}
}
void AllocMemory(char*** buf){
int bufSize = 10;
int stringSize;
**buf = calloc(bufSize, sizeof(char));
if(**buf == NULL){
printf("[ERROR] can't malloc %d bytes\n", bufSize);
exit(1);
}
char *readpos = **buf; //point to a pointer of your array!
while(1){ //looping until the alocated memory is enough to the inserted command
do{
fgets(readpos, bufSize, stdin); //reads a line from the specified stream
stringSize = strlen(**buf); //getting the size of the array
if (stringSize == 1)
{
printf("\nYou just pressed enter, pls type again: "); //checking if user just pressed enter
}
}while (stringSize == 1); //looping until user press only enter
if (readpos[strlen(readpos)-1] == '\n'){ //Search from the end as there's where the newline should be if exists, the string fits on array and doesnt need to allocate more memory
readpos[strlen(readpos)-1] = '\0'; //Remove \n from the string
break;
}
**buf = realloc(**buf, bufSize + stringSize * sizeof(char)); // Need to allocate more memory, because the before if its false
if(*buf == NULL){
printf("[ERROR] can't realloc more %d bytes\n", bufSize+1);
exit(1);
}
readpos = **buf + stringSize; // Set the pointer to next position to read into
}
}
I dont know if you are using global variables, but this dont have global variables! But if you want you can use them

IN C, after closed the program again open that program then how to store that intial value

I made one header file myh.h in which the username and password of particular person is given after withdrawing the money..and closed the program after open again then its shows actual value,not a change value(balance of that person)
myh.h header file ...for ex: username:parthin
Password:parthinb
Pressing 1
after 10 is press balance is 2,now again open then current balance how to change..
#include <stdio.h>
#include <string.h>
#include<conio.h>
const char *p[]={ "parthinb ", "baraiyab ","purvikbb " };
const char *u[]={"parthin","baraiya","purvik"};
int account(char name[10],int i)
{
int n,num;
int b[]={12,34,56};
printf("Welcome %s\n", name);
printf("Your current balance is:%d",b[i]);
printf("\n To Withdraw Money press 1:");
scanf("%d",&n);
switch(n)
{
case 1:
clrscr();
printf("Enter the money should to withdraw:");
scanf("%d",&num);
printf("\nYour current balance is::%d",b[i]-num);
b[i]=b[i]-num;
break;
}
return 0;
}
This is main program..
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "myh.h"
int main()
{
char un[20], pass[10], c;
int i;
start:
printf("Enter USER NAME::");
gets(un);
startp:
printf("Enter Password of 8 Digitis::");
for (i = 0; i < 8; i++)
{
c = getch();
pass[i]=c;
c = '*';
printf("%c", c);
}
pass[i] = ' ';
for(i=0;i<8;i++)
{
if(strcmp(un,u[i])==0)
break;
}
if (strcmp(un, u[i]) == 0)
{
if (strcmp(pass, p[i]) == 0)
{
printf("\nCORRECT\n");
account(un,i);
}
else
{
printf("\nPassword mis-match\n");
goto startp;
}
}
else
{
printf("\nUSER Name or password doesnot match..\n");
goto start;
}
}
as pmg said, you have to store data in a file or database to keep the updated balance after closing the program.
For your main program, its not a good idea to use goto statement, it makes your code not good to read. use loop or cut your program into functions.

Restaurant Program, when repeating, skips the first inputs

new to programming here :3
(Don't check my profile, I actually only know C, for now...)
I need help here, I dunno what's causing the problem, but whenever I repeat the program, it skips asking for a replacement value in
char C1.name
in function
void Name()
{
p("ENTER NAME: ");
gets(C1.name);
p("CONTACT DETAILS: ");
s("%d", &C1.cont_no);
}
in my Program
#include <stdio.h>
#include <windows.h>
#define p printf
#define s scanf
void Name();
void Order();
void Total();
void Receipt();
char Repeat();
/* CUSTOMER DETAILS */
struct CustomerOrder
{
char name[50];
long int cont_no;
int qty;
float price, total;
} C1;
main()
{
char cont;
/* Program Process... */
do{
Name();
Order();
Total();
Receipt();
cont = Repeat();
}while(cont == 'Y');
}
void Name()
{
/* ENTER NAME AND CONTACT DETAILS */
p("ENTER NAME: ");
gets(C1.name);
p("CONTACT DETAILS: ");
s("%d", &C1.cont_no);
}
void Order()
{
/* ENTER ORDERS */
p("HOW MANY ORDERS: ");
s("%d", &C1.qty);
C1.price = 59.99;
}
void Total()
{
/* TOTAL */
C1.total = C1.price * C1.qty;
p("TOTAL IS: %.2f", C1.total);
system("pause");
}
void Receipt()
{
system("cls");
/*PRINTED RECEIPT SAMPLE */
p("NAME IS: %s\n", C1.name);
p("CONTACT DETAILS: %d\n", C1.cont_no);
p("QTY: %d\n", &C1.qty);
p("PRICE EACH: %.2f\n", C1.price);
p("TOTAL PAYOUT: %.2f\n", C1.total);
}
char Repeat()
{
/* ASKS USER TO REPEAT PROGRAM, THEN RETURN VALUE TO BE USED BY function
main */
char repeat;
p("REPEAT?: ");
s("%s", &repeat);
return repeat;
}
There may be other problems you would probably notice (which I dunno if there are, but I would like it NOT to skip the Name part and stuff...
You only want to get a character when asking the user to repeat so change
s("%s", &repeat);
to
s(" %c", &repeat);
if you add a space ^ you will skip the \n that you entered previously.

How to format input to only accept integer values

input value 123 -- this value is integer, and valid
input value 1b23a -- this value is invalid
How do I detect which values are valid and not?
Here is my code:
#include <stdio.h>
#include <conio.h>
void main()
{
char str1[5],str2[5];
int num,num1,i;
num=0;
clrscr();
printf("Enter the Number ");
scanf("%s",str1);
for(i=0;str1[i]!='\0';i++)
{
if(str1[i]>=48&&str1[i]<=56)
num=num1*10+(str[i]-48);
else
{
printf("The value is invalid ");
}
}
printf("This Number is %d",num);
getch();
}
Please see this answer regarding use of strtol(). It is a safe way to convert arbitrary input that should be a string representation of an integer, while also saving 'garbage' bytes for additional analysis.
Using it, your code would look something like this:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#ifdef LINUX_VERSION
#include <curses.h>
#else
#include <conio.h>
#endif
#define BUFF_SIZE 1024
int main(void)
{
char str1[BUFF_SIZE], *garbage = NULL;
long num = 0;
printf("Enter the Number ");
scanf("%s",str1);
errno = 0;
num = strtol(str1, &garbage, 0);
if (errno) {
printf("The number is invalid\n");
return 1;
}
printf("You entered the number %ld\n", num);
if (garbage != NULL) {
printf("Additional garbage that was ignored is '%s'\n", garbage);
}
getch();
return 0;
}
This doesn't fix everything that is questionable about what you posted, but it should help you get off to a better start.
Output is:
tpost#tpost-desktop:~$ ./t
Enter the Number 1234abdc
You entered the number 1234
Additional garbage that was ignored is 'abdc'
Compiled via:
gcc -Wall -DLINUX_VERSION -o t t.c -lcurses
I'm not sure what platform you are using, so additional fixes to the code may be needed.
#include<stdio.h>
#include<conio.h>
void main()
{
char str1[5],str2[5];
int num,num1,i;
num=0;
clrscr();
printf("Enter the Number ");
scanf("%s",str1);
for(i=0;str1[i]!='\0';i++)
if(str1[i]>=48&&str1[i]<=56)
num=num1*10+(str[i]-48);
else
{
printf("The value is invalid ");
}
}
printf("This Number is %d",num);
getch();
}
One way is to use sscanf and check that there are no characters following the number. This is done most easily by adding a %c on the end and testing the return code, like this:
const char *yourString = ...;
int theValue, dummy;
if (sscanf(yourString, "%d%c", &theValue, &dummy) == 1) {
// Was a pure number, parsed into 'theValue'
} else {
// Either no number or had junk after it
}

Resources