How to execute the second function in C? - c

Whenever I enter the choice of 2, it does not execute the view_list() function. Instead it start it from first function which is new_acc(). Also the else is not working. How to solve this problem?
#include <stdio.h>
#include <stdlib.h>
int new_acc();
int view_list();
int main(){
int one=1, two=2;
int new_account, list;
printf("%d. Create new account\n",one);
printf("%d. View customers list\n",two);
printf("Enter you choice: ");
if (scanf("%d",&one)){new_account = new_acc();} // calling a function
else if (scanf("%d",&two)){list = view_list();} // calling a function
else {printf("Sorry this is not the correct option"); break;}
return 0;
}
int new_acc(){
char name;
printf("Enter your name: ");
scanf("%s",&name);
return 0;
}
int view_list(){
printf("view list");
return 0;
}

The return value of scanf() is the number of values it returns, not the actual value it self. Code should be:
int value = 0;
scanf("%d",&value);
if(value == one){new_account = new_acc();}
else if (value == two){list = view_list();}
else {printf("Sorry this is not the correct option"); break;}
Other recommendations:
The final break is not doing anything;
Indent your code it makes it much easier to read:
int value =0;
scanf("%d",&value);
if(value == one)
{
new_account = new_acc();
}
else if (value == two)
{
list = view_list();
}
else
{
printf("Sorry this is not the correct option");
}

The return value of scanf() is number of data read.
printf("Enter you choice: ");
if (scanf("%d",&one)){new_account = new_acc();} // calling a function
else if (scanf("%d",&two)){list = view_list();} // calling a function
else {printf("Sorry this is not the correct option"); break;}
should be like
printf("Enter you choice: ");
if (scanf("%d",&one)) != 1) { puts("input read error"); return 1; }
if (one == 1){new_account = new_acc();} // calling a function
else if (one == 2){list = view_list();} // calling a function
else {printf("Sorry this is not the correct option"); return 1;}
or
printf("Enter you choice: ");
if (scanf("%d",&one)) != 1) { puts("input read error"); return 1; }
switch (one) {
case 1: new_account = new_acc(); break; // calling a function
case 2: list = view_list(); break; // calling a function
default: printf("Sorry this is not the correct option"); break;
}
By the way, executing your new_acc() is dangerous.
%s specifier will accepts positive-length string while your buffer has space for only one character.
Even input of one-character string will cause buffer overrun because there will be terminating null character.
It should be like
int new_acc(){
char name[1024]; /* allocate an array */
printf("Enter your name: ");
scanf("%1023s",name); /* specify length limit (buffer size - 1 (terminating null character)) to avoid buffer overrun */
return 0;
}

Related

why for loop in program is not working correctly.it show display correct output but giving strange output

#include<stdio.h>
#include<string.h>
int main()
{
char username[5][10]={"akshay","shubham","gaurav","rahul","amit"};
int i,a=1;
char urname[10];
char pass[10];
printf("enter the Username : ");
scanf("%s",urname);
printf("enter the passwword : ");
scanf("%s",pass);
for(i=0;i<5;i++)
{
if(strcmp(&username[i][0],urname)==0) //username check
{
if(strcmp("helloworld",pass)==0) //password check
{
printf("correct username");
break;
}
else
printf("wrong pass");
break;
}
else
printf(" wrong username");
}
return 0;
}
//i wanted to make a login page but by some mean it is not working correctly please help me out...
Couple of things wrong with your code. First, the array size of 10 is insufficient for a string like "helloworld", in which we see 10 characters appear. You didn't count the '\0' byte at the end of the string. See this for details: What does the symbol \0 mean in a string-literal?
You also display an error immediately after you find a username mismatch. You should only do so in the end, after you have checked every entry in the username[][] array and perhaps set a flag.
#include <stdio.h>
#include <string.h>
int main(void)
{
char username[5][10] = {"akshay", "shubham", "gaurav", "rahul", "amit"};
int i, uname_flag = 0;
char urname[11];
char pass[11];
printf("enter the Username : ");
if (scanf("%10s", urname) != 1) // limit characters to be read to 10, to avoid buffer overflow
// also check the return value of scanf for input failure
{
return 1;
}
printf("enter the passwword : ");
if (scanf("%10s", pass) != 1)
{
return 1;
}
for (i = 0; i < 5; i++)
{
if (strcmp(username[i], urname) == 0) //username check
{
uname_flag = 1; // username is correct
if (strcmp("helloworld", pass) == 0) //password check
{
printf("correct username & pass");
break;
}
else
{
printf("wrong pass");
break;
}
}
}
if (uname_flag == 0) // check outside the loop
{
printf("wrong username\n");
}
return 0;
}

How do i get a program to loop until a character is entered?

What I'm exactly trying to achieve is: You enter your name, get a response like 'your name is', and if you enter a number you get a response like 'invalid input' which loops you back to the 'Enter your name' part
#include <stdio.h>
char i[20];
int result;
int main()
{
void findi(); // im trying to loop it back here if a number is entered instead of a character
printf("Enter your name\n");
result = scanf("%s", &i);
while(getchar() != '\n'){ //dont know how to make it work without the '!'
if(result = '%s'){
printf("Your name is: %s", &i);
return 0;
}
else{
printf("Invalid input"); //doesnt work
findi();
}
}
}
//program just ends after a character is entered instead of continuing
Using &i (char(*)[20]) for %s (expects char*) invokes undefined behavior.
The condition result = '%s' (assign implementation-defined value to result without checking its value) looks weird.
Calling findi() (not disclosed here) from main() need not mean a loop.
Try this:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char i[20];
printf("Enter your name\n");
/* an infinite loop (loop until return or break) */
for (;;) {
int number_exists = 0, j;
/* limit length to read and check the result*/
if (scanf("%19s", i) != 1) {
printf("read error\n");
return 1;
}
/* check if a number is entered */
for(j = 0; i[j] != '\0'; j++) {
if (isdigit((unsigned char)i[j])) {
number_exists = 1;
break;
}
}
/* see the result */
if (number_exists) {
/* one or more number is entered */
printf("Invalid input\n");
} else {
/* no number is entered : exit from the loop */
printf("Your name is: %s\n", i);
break;
}
}
return 0;
}

switch case not working with character value if i input char value the switch doesn't encounter default and starts linfinite loop

---------- > ## Heading ## > when i input a character as an input default case of switch doesn't encounter and loop started > infinite times > > > enter code here
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void create();
void display();
void search();
struct node {
int data;
struct node* link;
};
struct node* head;
int main()
{
int value;
while (1) {
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter Your Choice Here _________ ");
scanf(" %d", &value);
switch (value) {
case 1:
create();
break;
case 2:
display();
break;
case 3:
search();
break;
default:
printf("Error !! Wrong Choice :- \n");
break;
}
}
return 0;
}
TL;DR- Always check the return value of scanf() for success.
In case of a non-numeric character input, the format specifier %d does not find a match, and no input is consumed (i.e., the invalid input remains in the input buffer). Thus, the switch body executes, most likely it does not find a match with any existing case statement, so the default case statement(s) get executed, and control goes back to while loop.
Then, due to the presence of the invalid input in the buffer (and not getting consumed), the above phenomena keeps on repeating.
The major problem is, in case of scanf() failure, the value of variable value remains uninitialized and indeterminate. It does not construct a well-defined program.
Couple of things:
Always initialize local variables.
Always check for success of scanf() before using the returned value, if you have to use scanf(). For better use fgets() to take user input.
In case of failure of input using scanf(), clean up the input buffer before trying to read next input.
The break causes the program to exit the switch case but not the while. To wxit the while as well you should do something like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int value;
int done = 0;
while (!done) {
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter Your Choice Here _________ ");
scanf(" %d", &value);
switch (value) {
case 1:
printf("do stuff\n");
break;
case 2:
printf("do stuff\n");
break;
case 3:
printf("do stuff\n");
break;
default:
printf("Error !! Wrong Choice :- \n");
done = 1;
break;
}
}
return 0;
}
Here I used a variable initialized to 0 which indicates that the operation is not completed yet. When it's time to exit, the variable is set to 1, which causes the program to exit the while loop
Also, always remember to check the return value of printf(), to avoid possible errors
There is no break condition for while().
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void create();
void display();
void search();
struct node {
int data;
struct node* link;
};
struct node* head;
int main()
{
int value = 1;
while (value) {
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter 0 to exit :- \n");
printf("Enter Your Choice Here _________ ");
scanf(" %d", &value);
switch (value) {
case 1:
create();
break;
case 2:
display();
break;
case 3:
search();
break;
default:
printf("Error !! Wrong Choice :- \n");
break;
}
}
return 0;
}
if a non valid integer is enter for scanf(" %d", &value); value is not set and the invalid input is not flush => scanf will never block nor update value
you need to check scanf returns 1 (you read 1 value) and if not to flush the invalid input for instance reading all the line
so you can replace
scanf(" %d", &value);
switch (value) {
...
}
by
if (scanf("%d", &value) != 1) {
puts("invalid input");
while ((value = getchar()) != '\n') {
if (value == EOF) {
puts("EOF, exit");
exit(-1);
}
}
}
else {
switch(value) {
...
}
}
of course you can also manage the invalid input in your default case forcing an invalid value :
if (scanf("%d", &value) != 1) {
while ((value = getchar()) != '\n') {
if (value == EOF) {
puts("EOF, exit");
exit(-1);
}
}
value = -1; /* any value except 1,2 or 3 */
}
switch(value) {
...
}
Out of that you have no option to stop the execution, you can do :
...
puts("Enter 4 to exit :-);
...
switch (value) {
...
case 4:
exit(0);
...
}
I belive your intention is to run the program as long as "0" is not entered, but ter is no case for "0". also when we have scanf for %d and entering a "char" instead scanf will not read the char from buff. data on value will not get changed and it will keep printing existing data. (garbage if we enter invalid data first time itself, or any entered data.)
used fgets to read the input data, and do a scanf from buf, even when data is incorrect we are clearing the std input. so program will not get in to a infinite loop with scanf failure.
initilised "value = 0"
added case for "0".
scanf is replaced with fget +sscanf
#include <stdio.h>
#include <stdlib.h>
int main()
{
int value = 0;
char buff[256] = {0};
while (1) {
value = -1;
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter Your Choice Here _________ ");
fgets(buff, 255, stdin);
sscanf(buff, "%d", &value);
switch (value) {
case 1:
//create();
printf("case : 1\n");
break;
case 2:
//display();
printf("case : 2\n");
break;
case 3:
//search();
printf("case : 3\n");
break;
case 0 :
printf("case : 0 : Exiting program\n");
return 0;
default:
printf("Error !! Wrong Choice :- %d\n", value);
break;
}
}
return 0;
}

How do I add a contact to a phonebook program in C?

For my intro to programming class, we have to code a phonebook in C that lets users add contacts, as well as delete and display them. It also has to allocate and free memory as necessary (I tried to do this, but I honestly don't really know what I'm doing).
Anyway, I cannot figure out how to add a contact to the phonebook. I've pasted the relevant part of the program so far. It compiles, but it crashes every time I try to add a contact. Once I get this figured out, I think I can get the rest of the functions without too much trouble. If anyone could help me out, I'd really appreciate it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct entry {
char fname[20];
char lname[20];
char pnumber[20];
} entry;
// function prototypes
void addentry(int, entry*, char addfname[20], char addlname[20], char addpnumber[20]);
main() {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20] = { '\0' };
char addlname[20] = { '\0' };
char addpnumber[20] = { '\0' };
entry *pcontacts;
pcontacts = (entry*)calloc(1, (sizeof(entry)));
if (pcontacts == NULL) {
printf("No memory is available.");
free(pcontacts);
return 0;
}
while (1) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts);
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
pnum++;
printf("\nEnter first name: ");
scanf("%s", addfname);
printf("Enter last name: ");
scanf("%s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%s", addpnumber);
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
break;
}
} while (inputtest == 1);
}
}
void addentry(int pnum, entry *pcontacts, char addfname[20], char addlname[20], char pnumber[20]) {
pcontacts = (entry*)malloc(pnum * (sizeof(entry)));
if (pcontacts != NULL) {
strcpy(*pcontacts[pnum - 1].fname, addfname);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}
You get strings from standard input with scanf, but you should tell scanf the maximum number of bytes to store to the destination arrays to avoid buffer overruns:
scanf("%19s", addfname);
...
scanf("%19s", addlname);
...
scanf("%19s", addpnumber);
The way you call addentry is incorrect:
addentry(pnum, pcontacts, addfname[20], addlname[20], addpnumber[20]);
You actually try to read the byte just after the end of addfname, addlname and addpnumber. You should instead pass the arrays themselves, that will be passed to the function addentry as pointers to their first bytes:
addentry(pnum, pcontacts, addfname, addlname, addpnumber);
addentry should reallocate the array with realloc. It should be passed a pointer to the array pointer to it can update the pointer in main.
addentry does not copy the strings correctly: it only copies one, but with a syntax error.
Here is a corrected version:
void addentry(int, entry**, char addfname[20], char addlname[20], char addpnumber[20]);
int main(void) {
int selection = 0;
int inputtest = 1;
int pnum = 0; // keeps track of number of contacts
char addfname[20];
char addlname[20];
char addpnumber[20];
entry *pcontacts = NULL;
for (;;) {
do {
printf("\nPhonebook Menu\n\n");
printf("1:\tAdd contact\n");
printf("2:\tDelete contact\n");
printf("3:\tDisplay contacts\n");
printf("4:\tExit\n");
printf("\nChoose an action (1-4): ");
scanf("%d", &selection);
if (selection < 1 || selection > 4) {
printf("Invalid input. Please enter an integer between 1 and 4.\n");
inputtest = 0;
}
if (selection == 4) {
free(pcontacts); /* OK for NULL */
printf("\nThank you for using this phonebook.");
return 0;
}
switch (selection) {
case 1:
printf("\nEnter first name: ");
scanf("%19s", addfname);
printf("Enter last name: ");
scanf("%19s", addlname);
printf("Enter phone number (no spaces): ");
scanf("%19s", addpnumber);
addentry(pnum, &pcontacts, addfname, addlname, addpnumber);
pnum++;
break;
}
} while (inputtest == 1);
}
}
/* add an entry at position pnum */
void addentry(int pnum, entry **pp, char addfname[20], char addlname[20], char pnumber[20]) {
entry *pcontact = *pp;
pcontacts = realloc(pcontacts, (pnum + 1) * sizeof(entry));
if (pcontacts != NULL) {
*pp = pcontacts; /* update pointer in main */
strcpy(pcontacts[pnum].fname, addfname);
strcpy(pcontacts[pnum].lname, addlname);
strcpy(pcontacts[pnum].pnumber, addpnumber);
printf("\nContact has been added.");
} else {
printf ("No memory is available.\n");
}
}

Why is my static stack not working?

static stack implementation
this is also not deleting according to the lifo principle
static stack implementation:
it is not taking name for the second time
this is the new code now tell me why is it not working
please help
typedef struct student {
char name[20];
int roll;
int age;
} mystruct;
#define size 40
int top;
static mystruct s[size];
void push()
{
if (top == size - 1) {
printf("\noverflow"); //
} else {
printf("\nenter the name of the student");
gets(s[top].name);//not taking name for d 2 time
printf("\nenter the roll number");
scanf("%d", &s[top].roll);
printf("\nenter the age of the student");
scanf("%d", &s[top].age);
++top;
}
}
void pop()
{
if (top == -1)
{
printf("\nunderflow");
} else {
printf("%s", s[top].name);
printf("%d", s[top].roll);
printf("%d", s[top].age);
printf("\npopped");
--top;
}
}
void display()
{
int i;
if (top == -1) {
printf("\nstack is empty");
} else {
for (i = top; i > 0; i--) {
printf("\nthe name of the student is%s", s[top].name);
}
printf("\nthe roll no of the student is%d", s[top].roll);
printf("\nthe age of the student is%d", s[top].age);
}
}
main()
{
top = -1;
char ch;
while (1) {
printf("\nwelcome to static stack menu");
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n0.EXIT");
printf("\nplease enter your choice\n");
ch = getche();
if (ch == '0') {
break;
}
switch (ch) {
case '1':
push();
break;
case '2':
pop();
break;
case '3':
display();
break;
default:
printf("choice not valid");
break;
}
}
}
The first problem I noticed was that top is initialized to -1. Trying to access the member data of s[top] when top is initialized to -1 will result in unpredictable behavior.
I would suggest changing the line
top = -1;
to
top = 0;
That changes the basic assumption you have made in push, pop, and display about when the stack is empty and when it is full. Instead of checking if ( top == -1 ), you have to now check if (top == 0 ). Instead of checking if ( top == size - 1 ), you have to now check if ( top == size ).
In pop, you have to use top-1 instead of top.
The for loop in display is not scoped correctly. You need to use:
for (i = top-1; i >= 0; i--) {
printf("\nthe name of the student is %s", s[i].name);
printf("\nthe roll no of the student is %d", s[i].roll);
printf("\nthe age of the student is %d", s[i].age);
}
Also, reading the options for the menu and reading the subsequent input is little bit tricky.
After you read the menu option, you have to make sure that you eat up all the input until the next newline. Otherwise, gets() will read everything after your menu option until the end of the line. If you typed 1 for the menu and then typed Return/Enter, the name will be automatically accepted as "\n". Hence, I suggest the lines:
printf("\nwelcome to static stack menu");
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n0.EXIT");
printf("\nplease enter your choice\n");
ch = fgetc(stdin);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
Also, after you read the age of the object, you have to eat everything up to the newline. Otherwise, the newline character is read in as the choice for the next menu option.
scanf("%d", &s[top].age);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
Here's the fully working file. I have replaced gets by fgets and getche by fgetc.
#include <stdio.h>
#include <string.h>
typedef struct student {
char name[20];
int roll;
int age;
} mystruct;
#define size 40
int top;
static mystruct s[size];
void push()
{
if (top == size) {
printf("\noverflow"); //
} else {
printf("\nenter the name of the student: ");
fgets(s[top].name, 20, stdin);//not taking name for d 2 time
// The newline character is part of s[top].name when fgets is
// finished. Remove that.
s[top].name[strlen(s[top].name)-1] = '\0';
printf("\nenter the roll number: ");
scanf("%d", &s[top].roll);
printf("\nenter the age of the student: ");
scanf("%d", &s[top].age);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
++top;
}
}
void pop()
{
if (top == 0)
{
printf("\nunderflow");
} else {
printf("%s, ", s[top-1].name);
printf("%d, ", s[top-1].roll);
printf("%d", s[top-1].age);
printf("\npopped");
--top;
}
}
void display()
{
int i;
if (top == 0) {
printf("\nstack is empty");
} else {
for (i = top-1; i >= 0; i--) {
printf("\nthe name of the student is %s", s[i].name);
printf("\nthe roll no of the student is %d", s[i].roll);
printf("\nthe age of the student is %d", s[i].age);
}
}
}
main()
{
top = 0;
char ch;
while (1) {
printf("\nwelcome to static stack menu");
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n0.EXIT");
printf("\nplease enter your choice\n");
ch = fgetc(stdin);
/* Skip till the end of line is read. */
while ( fgetc(stdin) != '\n' );
if (ch == '0') {
break;
}
switch (ch) {
case '1':
push();
break;
case '2':
pop();
break;
case '3':
display();
break;
default:
printf("choice, %c, not valid", ch);
break;
}
}
}
You need to change getche() to getchar()
Note: getche() is a non-standard function.
Maybe this will be useful http://www.delorie.com/djgpp/doc/libc/libc_385.html
Pay attention to implementation note:
"If you can detect the situation when one of the conio functions is called for the very first time since program start, you could work around this problem by calling the gppconio_init function manually"
or just replace it with getchar(). And there meaned conio included.

Resources