This is a mini project for library management system. The problem is that first fgets function for user input in case 1 falls through no matter the content but that of the subsequent ones works. I want to accept the full name of the book name and the author which contains whitespaces from the console.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
// Structure definition
struct library
{
char bookName[50];
char authorName[50];
int numberOfPages;
float price;
};
int main()
{
// Structure Variable declaration
struct library lib[50];
// Variables initialization
int i,j,keepcount;
i=j=keepcount = 0;
// Character arrays
char arth_nm[50],book_nm[50];
while(j!=7)
{
// Menu Selection
printf("\n\n1. Add book information\n2. Display book information\n");
printf("3. List all books of given author\n");
printf("4. List the title of specified book\n");
printf("5. List the count of books in the library\n");
printf("6. Display Highest Price Book\n");
printf("7. Exit");
printf ("\n\nSelect one of the above: \n");
scanf("%d",&j);
switch(j)
{
// Entering book details
case 1:
printf ("Enter book name: ");
fgets(lib[i].bookName, sizeof(lib[i].bookName), stdin);
printf ("Enter author name: ");
fgets(lib[i].authorName, sizeof(lib[i].authorName), stdin);
printf ("Enter pages: ");
scanf ("%d",&lib[i].numberOfPages);
printf ("Enter price: ");
scanf ("%f",&lib[i].price);
keepcount++;
break;
// All book details entered
case 2:
printf("You have entered the following information\n");
for(i=0; i<keepcount; i++)
{
printf ("Book name = %s",lib[i].bookName);
printf ("\tAuthor name = %s",lib[i].authorName);
printf ("\tPages = %d",lib[i].numberOfPages);
printf ("\tPrice = %f",lib[i].price);
printf("\n");
}
break;
// Searching for book details by using the name of the Author
case 3:
printf ("Enter author name : ");
scanf ("%s",arth_nm);
for (i=0; i<keepcount; i++)
{
if (strcmp(arth_nm, lib[i].authorName) == 0)
printf ("%s %s %d %f",lib[i].bookName,lib[i].authorName,lib[i].numberOfPages,lib[i].price);
}
break;
// Searching for book details by using the name of the book
case 4:
printf ("Enter book name : ");
scanf ("%s",book_nm);
for (i=0; i<keepcount; i++)
{
if (strcmp(book_nm, lib[i].bookName) == 0)
printf ("%s \t %s \t %d \t %f",lib[i].bookName,lib[i].authorName,lib[i].numberOfPages,lib[i].price);
}
break;
// Case for Total many of books shelved
case 5:
printf("\n No of books in library : %d", keepcount);
break;
// Case for Highest paid book
case 6:
printf ("Highest Price Book : ");
float temp = 0;
for (i=0;i<keepcount;i++)
{
if(temp < lib[i].price)
temp = lib[i].price;
}
printf("%f", temp);
break;
case 7:
exit (0);
}
}
return 0;
}
Use the fgets() statement for accepting whitespaces:
fgets(arth_nm, 50, stdin);
You should fflush(stdout) it to clear the output buffer like this:
fflush(stdout);
fgets(arth_nm, 50, stdin);
It'll help you to fix this.
yes , there is, as #Rohan Bari said, you can use fgets() , though some compilers does not supports the use of this function. Alternatively, you can use
scanf ("%[^\n]%*c", variableName);
this function takes the input till a new line or enter is pressed, i.e, it will read any character including whitesapces.i hope i've been able to help.
I have the following piece of code:
#include <stdio.h>
#include <stdlib.h>
int main (){
int s1 = 0;
int s2 = 0;
int frstEscolha;
do{
printf("\n\n WELCOME \n\n");
printf(" 1- JOGAR \n");
printf(" 2- SAIR \n");
scanf ("%d", &frstEscolha);
printf ("%d %d",s1,s2);
switch (frstEscolha) {
system ("cls");
int sndEscolha;
case (1):
s1 = 1;
printf ("\n\n NUMBER OF PLAYERS \n\n");
printf ("1- ONE PLAYER \n");
printf ("2- TWO PLAYERS \n");
scanf ("%d", & sndEscolha);
system ("cls");
do{
switch (sndEscolha) {
char *trdENome , *trdENome1, *trdENome2;
case (1):
s2 = 1;
printf ("\nPLAYER NAME: \n");
scanf ("%s", &trdENome);
printf("\nGOOD GAME %s \n\n", &trdENome);
case (2):
s2 = 1;
printf ("\nPLAYER 1 NAME \n");
scanf ("%s", &trdENome1);
printf ("\nPLAYER 2 NAME \n");
scanf ("%s", &trdENome2);
printf("\nGOOD GAME %s e %s \n\n", &trdENome1, &trdENome2);
default :
printf ("Invalid character, try again!!");
s2 = 0;
}
}
while (s2==0);
case (2): exit (0);
default :
printf ("Invalid character, try again!!");
s1 = 0;
}
}
while (s1 == 0);
return 0;
}
This is supposed to print a menu and let you choose your options to navigate the different menus, the while is used for repeating the process when the character inserted is not valid, but when this happens the console starts flickering and the program chrashes. How is this caused, and how can i fix it?
Thanks
After running your code, nothing seems to flicker uncontrollably and the program runs perfectly fine. Nothing crashes or bugs. The only problem in your code is your switch statement. They end up in an infinite loop. What I recommend is to put a break; at the end of each case to get out of that loop. Other than that, your code seems to run fine.
The following code is only to fix the infinite loop problem in the switch statement
case(1):
//your code here
break;
I believed I found the error to your code. In you brief description regarding your problem, I happened to find the error. In you first scanf, if the user inputs a character, the program breaks. My compiler kept on repeating the question.
What I recommend is to use if/else loops to solve your problem. Another solution is to change int frstEscolha to unsigned int frstEscolha. If the user happens to input a char, it could the value for a character without breaking the program. But highly recommend using if/else in this case.
If you are using unsigned int, the scan works like this.
scanf("%lf", &varName);
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 6 years ago.
This is a part of my 'Phonebook' program.
void viewone(){
char name[25], fname[25];
int n, ncheck, op;
fp = fopen("Phonebook.txt","r");
printf ("\n Search by : \n 1: Name\n 2: Phone Number\n");
printf ("Enter option : ");
scanf ("%d",&op);
switch(op){
case 1:
printf ("\n Enter Name : ");
scanf ("%s",name);
fscanf(fp, "%s %d", fname, &ncheck);
while (!feof(fp)){
printf ("\n\n %s \n\n",fname);
if (fname == name){ \\ Problem in here
printf ("\n\n Contact Found...\n");
printf (" %s +880%d", fname, ncheck);
break;
}
else{
fscanf(fp, "%s %d", fname, &ncheck);
}
if (feof(fp)){
printf ("\n\n Contact Not Found...\n\n");
}
}
menu();
break;
case 2:
printf ("\n\n Enter Contact Number (+880) : ");
scanf ("%d",&n);
fscanf(fp, "%s %d", fname, &ncheck);
while (!feof(fp)){
if (ncheck == n){
printf ("\n\n Contact Found...\n");
printf (" %s +880%d\n", fname, ncheck);
break;
}
else{
fscanf(fp, "%s %d", fname, &ncheck);
}
if (feof(fp)){
printf ("\n\n Contact Not Found...\n\n");
}
}
menu();
break;
default:
printf ("\n Wrong option...\n\n");
viewone();
break;
}
}
When it comes to the marked line, the program should search the file for the 'fname' character until it matches the 'name' character. But though they match, nothing happens and the program still goes on. And in the end, it does what is told in the else statement. My question is why is this happening and how can i fix it?
My program runs perfectly when i search with phone number. But why is it not happening with character?
Comparing string is not done by ==. Instead use string compare function like this
strcmp(fname,name)
When I execute the program it asks me for my name if I put more than one letter it has an error and it shuts down and in the second one anyting I put it fails and closes instantly
#include <stdio.h>
int main () {
char firstname[20];
char lastname[20];
char response[20];
printf ("Type your first name:\n");
scanf ("'c'",&firstname);
printf ("\n");
printf ("Type your last name:\n");
scanf ("'c'",&lastname);
printf ("\n");
printf ("Hi %s %s do you want to stop giving me information?\nSay Y or N");
scanf ("%s",&response);
if (response == 'Y' || response == 'y'); {
system ("pause<NULL");
}
printf("Thank you for using my program. Good Bye!\n\n");
system ("pause<NULL");
}
There are many issues:
You probably want this (untested code)
#include <stdio.h>
int main () {
char firstname[20];
char lastname[20];
char response[20];
printf ("Type your first name:\n");
scanf ("%s", firstname);
printf ("\n");
printf ("Type your last name:\n");
scanf ("%s", lastname);
printf ("\n");
printf ("Hi %s %s do you want to stop giving me information?\nSay Y or N", firstname, lastname);
scanf ("%s",response);
if (response[0] == 'Y' || response[0] == 'y') {
system ("pause<NULL");
}
printf("Thank you for using my program. Good Bye!\n\n");
system ("pause<NULL");
return 0;
}
There is no 'c' format specifier, it's %s
scanf ("%s", &firstname) is wrong, firstname is already the address of the buffer
response == 'y'is wrong, response is the address of the buffer, you just need the first char of the buffer, that is responde[0]
if (response[0] == 'Y' || response[0] == 'y'); {, there was a stray ; before the {
Your problem is that you are asking for a char input, you want a string.
tutorialspoint has a simlpe and claean example.
https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm
Sorry about the previous code, I did not correctly interpreted the situation.
What's happening is the string is being stored with spaces but when i am trying to read it afterwards, The output flickers continuously (its like its reading it over and over again and printing it infinitely on itself.)
The records are stored in a file named record.dat
I am inserting image showing file contents stored after I input a new record in the file (Everything gets stored correctly here)
![These are the contents of record.dat right after i insert the new record]--> the image --> http://i.stack.imgur.com/YxGEd.png
and now when I try to look the details of this record on my application I get this.
![Output showing the record details but not entirely correct as " Finch" is missing] -- >> the image -- >> http://i.stack.imgur.com/zgmGY.png
and after this if i close the application and then start it again and try to read the previous data it shows this:
![This output is also flickering like before but now even the data is gone]-->> the image -->> http:// i.stack.imgur.com/ 4q0qb.png
(and just in case you are wondering -- the data is still there in the record.dat file -- all of it which i entered when i prevously created the record.)
I hope the problem is more clear now.....
void see(void)
{
FILE *ptr;
int test=0,rate;
int choice;
float time;
float intrst;
char c;
ptr=fopen("record.dat","r");
printf("Do you want to check by\n1.Account no\n2.Name\nEnter your choice:");
//Selection Choice with Validation
int once = 0;
do
{
if(once!=0)
{
printf("\nThe choice is invalid.\nEnter 1 for account number and 2 for name");
}
once = once+1;
} while ((scanf("%d%c", &choice, &c)!=2 || c!='\n') && clean_stdin());
if (choice==1)
{
//Account Number with Validation
once = 0;
do
{
if(once!=0)
{
printf("\nThe above account number is invalid.\nEnter an account number (numeric value only):");
}
else
{
printf("\nEnter an account number:");
}
once = once+1;
} while ((scanf("%d%c", &check.acc_no, &c)!=2 || c!='\n') && clean_stdin());
while (fscanf(ptr,"%d %s %d/%d/%d %d %s %s %lf %s %f %d/%d/%d",&add.acc_no,add.name,&add.dob.month,&add.dob.day,&add.dob.year,&add.age,add.address,add.citizenship,&add.phone,add.acc_type,&add.amt,&add.deposit.month,&add.deposit.day,&add.deposit.year)!=EOF)
{
if(add.acc_no==check.acc_no)
{ system("cls");
test=1;
printf("\nAccount NO.:%d\nName:%s \nDOB:%d/%d/%d \nAge:%d \nAddress:%s \nCitizenship No:%s \nPhone number:%.0lf \nType Of Account:%s \nAmount deposited:$ %.2f \nDate Of Deposit:%d/%d/%d\n\n",add.acc_no,add.name,add.dob.month,add.dob.day,add.dob.year,add.age,add.address,add.citizenship,add.phone,
add.acc_type,add.amt,add.deposit.month,add.deposit.day,add.deposit.year);
if(strcmpi(add.acc_type,"fixed1")==0)
{
time=1.0;
rate=9;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $%.2f as interest on %d/%d/%d",intrst,add.deposit.month,add.deposit.day,add.deposit.year+1);
}
else if(strcmpi(add.acc_type,"fixed2")==0)
{
time=2.0;
rate=11;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d/%d/%d",intrst,add.deposit.month,add.deposit.day,add.deposit.year+2);
}
else if(strcmpi(add.acc_type,"fixed3")==0)
{
time=3.0;
rate=13;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d/%d/%d",intrst,add.deposit.month,add.deposit.day,add.deposit.year+3);
}
else if(strcmpi(add.acc_type,"saving")==0)
{
time=(1.0/12.0);
rate=8;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d of every month",intrst,add.deposit.day);
}
else if(strcmpi(add.acc_type,"current")==0)
{
printf("\n\nYou will get no interest\a\a");
}
}
}
}
else if (choice==2)
{
printf("Enter the name:");
scanf("%s",&check.name);
while (fscanf(ptr,"%d %s %d/%d/%d %d %s %s %lf %s %f %d/%d/%d",&add.acc_no,add.name,&add.dob.month,&add.dob.day,&add.dob.year,&add.age,add.address,add.citizenship,&add.phone,add.acc_type,&add.amt,&add.deposit.month,&add.deposit.day,&add.deposit.year)!=EOF)
{
if(strcmpi(add.name,check.name)==0)
{ system("cls");
test=1;
printf("\nAccount No.:%d\nName:%s \nDOB:%d/%d/%d \nAge:%d \nAddress:%s \nCitizenship No:%s \nPhone number:%.0lf \nType Of Account:%s \nAmount deposited:$%.2f \nDate Of Deposit:%d/%d/%d\n\n",add.acc_no,add.name,add.dob.month,add.dob.day,add.dob.year,add.age,add.address,add.citizenship,add.phone,
add.acc_type,add.amt,add.deposit.month,add.deposit.day,add.deposit.year);
if(strcmpi(add.acc_type,"fixed1")==0)
{
time=1.0;
rate=9;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d/%d/%d",intrst,add.deposit.month,add.deposit.day,add.deposit.year+1);
}
else if(strcmpi(add.acc_type,"fixed2")==0)
{
time=2.0;
rate=11;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d/%d/%d",intrst,add.deposit.month,add.deposit.day,add.deposit.year+2);
}
else if(strcmpi(add.acc_type,"fixed3")==0)
{
time=3.0;
rate=13;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d/%d/%d",intrst,add.deposit.month,add.deposit.day,add.deposit.year+3);
}
else if(strcmpi(add.acc_type,"saving")==0)
{
time=(1.0/12.0);
rate=8;
intrst=interest(time,add.amt,rate);
printf("\n\nYou will get $.%.2f as interest on %d of every month",intrst,add.deposit.day);
}
else if(strcmpi(add.acc_type,"current")==0)
{
printf("\n\nYou will get no interest\a\a");
}
}
}
}
fclose(ptr);
if(test!=1)
{ system("cls");
printf("\nRecord not found!!\a\a\a");
see_invalid:
printf("\nEnter 0 to try again,1 to return to main menu and 2 to exit:");
scanf("%d",&main_exit);
system("cls");
if (main_exit==1)
menu();
else if (main_exit==2)
close();
else if(main_exit==0)
see();
else
{
system("cls");
printf("\nInvalid!\a");
goto see_invalid;}
}
else
{printf("\nEnter 1 to go to the main menu and 0 to exit:");
scanf("%d",&main_exit);}
if (main_exit==1)
{
system("cls");
menu();
}
else
{
system("cls");
close();
}
}
The recommended solution is not to use scanf since scanf is also vulnerable to buffer overflows. In any case, you are not actually doing any formatting with the scanf call. You can use fgets to read the input into a string and specify the maximum number of characters that you allow. Use something like the following:
printf("\nEnter the name: ");
fgets(add.name, MAX_NAME_SZ, stdin);
You can use the %[^...] format specifier to read spaces into a string. Here's an example program that hopefully gives you something to work from.
#include <stdio.h>
int main()
{
char const* line = "This is a string, 10";
char text[50];
int number;
// Read up to 49 characters not including ',' to text.
sscanf(line, "%49[^,], %d", text, &number);
printf("%s, %d\n", text, number);
return 0;
}
Output:
This is a string, 10
I think you should provide an example of a failing situation or at least clean up the code and only give us the buggy part.
I see a lot of printf use without \n at the end which I know can be a problem (which may aswell be completely out of the subject here).
Since I've never used scanf I can't tell where your error is but maybe if you reduced your code to the acquisition of the user's input (-> the scanf part) then an attempt to display it (-> the part where your string gets truncated as it meets the first space) we could easily help you fix that problem faster and would be nicer to read.