Unexpected random characters printed by library management program [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am working on a school project where I have to make a program that let the user enter information about new books, delete books or display all registered books.
The unexpected behavior is when I choose to display all books : THE SECOND BOOK'S TITLE ALWAYS print some strange random characters or about 15 empty lines while the rest remain normal.
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int Pages,RlsYear,AtrNbr; //"Pages" stands for "the number of pages", "RlsYear" stands for "Release Year"
char Title[128],Genre[128],Authors[256];
}book;
int main()
{
int i,nb;
char ch1,Tmp[128],cln;
book* b = malloc(1 * sizeof(book));
nb=0;
puts("\n Enter your choice : ");
ch1=getch();
while (ch1 != EOF && ch1 != 'q')
{
switch(ch1) {
case 'n': // N to enter a new book
case 'N':
{
printf("\n enter the book's Title : ");
gets(b[nb].Title);
printf(" enter the book's Genre : ");
gets(b[nb].Genre);
printf(" how many pages does the book have ? ");
scanf("%d",&b[nb].Pages);
gets(cln); //i added those "gets(cln)" to avoid problems from "scanf" so you can just ignore them
printf(" when was the book released (year)? ");
scanf("%d",&b[nb].RlsYear);
gets(cln);
printf(" how many authors does this book have ? ");
scanf("%d",&b[nb].AtrNbr);
gets(cln);
strcpy(b[nb].Authors,"");
for(i=0;i<b[nb].AtrNbr;i++)
{
printf("\t\t enter the %d author : ",i+1);
gets(Tmp);
strcat(b[nb].Authors,Tmp);
strcat(b[nb].Authors," | ");
}
nb=nb+1;
book* B = realloc(b, nb+1 * sizeof(book));
b = B;
}
break;
case 'i': // I to display registered books
case 'I':
{
for(i=0;i<nb;i++)
printf("\n %s",b[i].Title);
}
break;
default:
printf("unknown choice !");
break;
}
puts("\n Enter your choice : ");
ch1=getch();
}
return 0;
}

I solved the problem when i changed the b.Title size from 128 to 60.
Apparently the problem appears when the b.Title size passes 80.
Can someone explain please? i'm more confused now

Related

Is there a better way to accept full name of user in structures from the console in C language?

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.

If(int IDnumvariable == structname[counter].IDnumber) Not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Im stuck on a situation with my book borrow function, The problem is when i have to compare user entered teacher id with an existing id in the teacherfile.
my id data types for both are integer so i used:
void tborrow() //2.1
{
int bksb=0;
int tbid2 =0;
struct books book[50];
struct teachers teach[50];
int x=0;
int c=0;
int i=0;
int tid=0;
int tid2=0;
int tbid=0;
FILE *teacherp;
FILE *bkbp;
teacherp= fopen("TeacherFile.txt", "r+");
if(teacherp!=NULL) //Checks if Teacher File was created successfully
{
printf("Teacher File Successfully Opened\n\n\n");
printf("Enter Teacher's ID# :");
scanf("%d",&tid);
while(1) // Loop till end of file
{
fflush(stdin);////flushes buffer
fscanf(teacherp,"%s %d %s %s %d ",teach[i].Teachname,&teach[i].IDnum,teach[i].contactnum,teach[i].Faculty,&teach[i].bksborrowed);
tid2= tid2 + teach[i].IDnum;
if (tid == tid2)
{
system("cls");
printf("Teacher ID Confirmed\n\n");
printf("\n\n----Teacher Information-----"); //check if correctly entered
printf("\nName: %s ", teach[i].Teachname);
printf("\nID #: %d " ,teach[i].IDnum);
printf("\nContact #: %s ", teach[i].contactnum);
printf("\nFaculty: %s " ,teach[i].Faculty);
printf("\nBooks Borrowed: %d " ,teach[i].bksborrowed);
printf("\n-----------------------------\n");
printf("\nIs your account? 1-Yes 0=No : ");
scanf("%d",&c);
fflush(stdin);//flushes buffer after scanf
if (c==1)//if yes find and borrow book
{
bksb = bksb+teach[i].bksborrowed;
if (bksb < 2)// if teacher has less than 2 books borrowed
{
printf("\nThis account currently has %d books borrowed",teach[i].bksborrowed);
bkbp = fopen("BookFile.txt","r+");
if(bkbp!=NULL) //Checks if Book File was created successfully if yes search for book and borrow
{
printf("Enter Book ISBN # :");
scanf("%d",&tbid);
while(1)
{
fscanf(bkbp,"%s %s %d %d %s %d %d-%d-%d %d-%d-%d ",book[x].Title, book[x].Author, &book[x].Accessionnum, &book[x].ISBN, book[x].Available, &book[x].bid, &book[x].bdate->m, &book[x].bdate->d, &book[x].bdate->y, &book[x].rdate->m, &book[x].rdate->d, &book[x].rdate->y);
tbid2 = tbid2 + book[x].ISBN;
if (tbid == tbid2)
{
printf("\n\n-------Book Information-------"); //check if correct book found
printf("\nTitle: %s", book[x].Title);
printf("\nAuthor: %s" ,book[x].Author);
printf("\nAccession#: %d" ,book[x].Accessionnum);
printf("\nISBN#: %d", book[x].ISBN);
printf("\nAvailability(Y-N): %s" ,book[x].Available);
printf("\nBorrowers ID#: %d ",book[x].bid);
printf("\nBorrow Date: %d-%d-%d ",book[x].bdate->m,book[x].bdate->d,book[x].bdate->y);
printf("\nReturn Date: %d-%d-%d ",book[x].rdate->m,book[x].rdate->d,book[x].rdate->y); //Prints user entry to screen for confirmation
printf("\n------------------------------\n");
printf("\nIs this the book you are looking for? 1-Yes 0=No : ");
scanf("%d",&c);
fflush(stdin);//flushes buffer after scanf
if (c==1)//if yes print into file
{
book[x].bid=tid2;
bksb++;
teach[i].bksborrowed=bksb;
printf("\n Book %s has been borrowed by %s %d",book[x].Title,teach[i].Teachname,teach[i].IDnum);
fclose(bkbp);
printf("\n\nReturning to previous account");
_getch();
break;
TeacherAcc();
}
/*else
{
fclose(bkbp);
system("cls");
printf("\nStarting over book borrowing!");
break;
tborrow();
}*/
}
else
//if we encountered the end of the file on the last attempt
//to read data then break out of the read loop
if( feof(bkbp) ) //If end of file is reached break out of loop
{
break;
}
++x;
}
}else // if book file failed to open
{
printf("Error!, Restarting Teacher Book Borrowing System. Press Enter to continue");
getchar();
tborrow();
}
}else if (teacher[i].bksborrowed == 2) // if teacher has already borrowed 2 books
{
printf("\nThis account already has %d books borrowed",teach[i].bksborrowed);
printf("\nGoing back to previous menu");
_getch();
system("cls");
TeacherAcc();
}
}
else if (c==0) //runs the Teacher borrow function if wrong account
{
system("cls");
printf("\nRe-Enter Teacher ID!");
tborrow();
}
}else // else if teacher id not found
{
printf("\nID %d not found, Please re-enter a valid ID \n Press enter to try again",tid);
_getch();
system("cls");
tborrow();
}
if( feof(teacherp) ) //If end of file is reached break out of loop
{
break;
}else
i++;
}//end of continuous loop
fclose(teacherp); //close the file when done
} //if file created successfully
else //Teacher file failed to load, restarts function to correctly open Teacher
{
printf("Error!, Restarting Teacher System. Press Enter to continue");
getchar();
system("cls");
}
printf("\n\nReturning to previous menu, Press Enter to continue \n");
fflush(stdin);//flushes buffer so getchar works properly
getchar();
system("cls");
TeacherAcc();
}//borrow function end
but it is not correctly comparing or storing the id i read from the file, and the file exists and the has the stored id for tests
attached is the block of code from my teacher borrow function
any help would be appreciated
i was thinking of making the id datatypes char and use strcmp(userentered,struct[count].idnum)
(form the comments)
Remove tid2= tid2 + teach[i].IDnum;.
Yes, you can use if (tid == teach[i].IDnum)
However, look at what your while(1) loop in tborrow is doing:
while(1)
read a teacher from the file
is the teacher the right one?
yes - do something
no - print an error and recursively call tborrow again.
Think about how you would do this if you were looking for a teacher by hand in a list on paper - would you look at the first teacher in the list, then give up and start again if it wasn't the right one?

if statement using char string - wont recognize string [duplicate]

This question already has answers here:
Using the equality operator == to compare two strings for equality in C [duplicate]
(9 answers)
Closed 8 years ago.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
int main()
{
bool flag= true;
int menu_option;
char first_band [16], second_band [16], third_band [16], fourth_band [16], green[16];
while (flag)
{
printf("Please choose an option:\n");
printf("To run the program, enter 1.\n");
printf("For help, enter 2.\n");
printf("To exit, enter 3.\n");
scanf("%i", &menu_option);
switch (menu_option)
{
case 1:
printf("Please enter the colour of the first band on the resistor:\n");
scanf(" %s", first_band);
printf("Please enter the colour of the second band on the resistor:\n");
scanf(" %s", second_band);
printf("Please enter the colour of the third band on the resistor:\n");
scanf(" %s", third_band);
printf("Please enter the colour to fourth band ont he resistor. If there is no fourth band, enter 'null'.\n");
scanf(" %s", fourth_band);
flag=false;
break;
case 2:
flag=true;
printf("program instructions");
break;
case 3:
flag=false;
return 0;
break;
default:
flag=true;
printf("Invalid command.\n");
break;
}
}
printf("%s", first_band);
if (first_band == "green")
printf("the first band is %c\n", first_band);
return (0);
}
So i can't get the last "if" statement to print "the first band is %s". the print statement right above it is to see if the program is even reading the user input...which it seems to be. It just won't seem to recognize the word and execute the if statement. I feel like my syntax is wrong when dealing with the char strings, which is causing this problem, but I'm new to this so a helping hand would be much appreciated.
You have to use strcmp() instead.
if (strcmp(first_band, "green") == 0)
printf("the first band is %c\n", first_band);

c programming: stopping endless loops [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have been trying to get my head around validating the code, a.k.a stopping the program from breaking and entering the endless loops but I find it quite difficult.
So far I have come across multiple points in the program where the user can break it by entering the wrong input for example with the main menu if the user enters a letter or symbol instead of a number the program enters the endless loop, so a basic guide on validating would be helpful.
#include <stdio.h>
#include <stdlib.h>
struct packet{
int source;
int destination;
int type;
int port;
char data[50];
};
void main ()
{
struct packet s[50]; //Array for structure input
int choice;
int customerCount = 0, ii = 0;
while (customerCount <= 50){
printf("What would you like to do?\n");
printf("\t1) Add a packet.\n");
printf("\t2) s all packets.\n");
printf("\t3) Save packets.\n");
printf("\t4) Clear all packets.\n");
printf("\t5) Quit the programme.\n");
scanf("%i", &choice);
switch (choice)
{
case 1: printf("\n****Adding a packet*****\n");
printf("Where is the packet from?\n");
scanf("%i", &s[customerCount].source);
printf("Where is the packet going?\n");
scanf("%i", &s[customerCount].destination);
printf("What type is the packet?\n");
scanf("%i", &s[customerCount].type);
printf("What is the packet's port?\n");
scanf("%i", &s[customerCount].port);
printf("Enter up to 50 characters of data.\n");
scanf("%s", s[customerCount].data);
customerCount++;
break;
case 2: printf("\nDisplaying Infomation\n");
for(ii = 0; ii < customerCount; ii++) {
printf("\nSource: %d", s[ii].source);
printf("\nDestination: %d", s[ii].destination );
printf("\nType : %d", s[ii].type);
printf("\nPort : %d", s[ii].port);
printf("\nData: %s\n---\n", s[ii].data);
}
break;
case 3: break;
case 4: break;
case 5: break;
default: printf("\nThis is not a valid choice, please choose again\n\n");
break;
}
}
}
scanf returns the number of arguments it successfully scanned.
Checking for proper input and rejecting bad input can be as simple as:
printf("Where is the packet from?\n");
while(scanf("%i", &s[customerCount].source) != 1)
{
while(getchar() != '\n')
continue;
}
This is not very robust, however, and something like validating user input should be very robust. Assume the user will always enter wrong input... it's sad but true.

Having an issue with structs and the program not saving inputs. I am inexperienced [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
The compiler doesn't come up with any errors...It is supposed to be a basic phonebook with 5 slots for people. For some reason everything seems to work but it doesn't save the information. What did I do wrong?
typedef struct contact{
char fname[10];
char lname[10];
int pnumber;
};
struct contact p1;
struct contact p2;
struct contact p3;
struct contact p4;
struct contact p5;
int go =0;
int phonebook(struct contact person,int use);
int main(){
while(go == 0){
int contact;
int choice;
int location;
printf("first what position in your contacts would you like to change?(1-5)\n");
scanf("%d",&location);
printf("what would you like to do?\n1. add a contact\n2. change a contact\n3. print a
contact\n4. Quit\n");
scanf("%d",&choice);
switch(location){
case 1:
phonebook(p1,choice);
break;
case 2:
phonebook(p2,choice);
break;
case 3:
phonebook(p3,choice);
break;
case 4:
phonebook(p4,choice);
break;
case 5:
phonebook(p5,choice);
break;
default:
printf("that was not a valid option\n");
}
}
system("PAUSE");
return EXIT_SUCCESS;
}
int phonebook(struct contact person,int use){
switch(use){
case 1:
if(person.pnumber>0){
printf("you already have a contact there\n");
}
else{
printf("What is the contact's first name?\n");
scanf("%s", &person.fname);
printf("\nWhat is the contact's last name?\n");
scanf("%s", &person.lname);
printf("\nWhat is the contact's phone number?\n");
scanf("%d", &person.pnumber);
}
break;
case 2:
if(person.pnumber == 0)
printf("No contact is saved in this position\n");
else{
printf("What is the contact's first name?\n");
scanf("%s", &person.fname);
printf("\nWhat is the contact's last name?\n");
scanf("%s", &person.lname);
printf("\nWhat is the contact's phone number?\n");
scanf("%d", &person.pnumber);
}
break;
case 3:
printf("\nName:%s\n%s \nNumber:%d \n",&person.fname,&person.lname,&person.pnumber);
break;
case 4:
go = 1;
break;
default:
printf("that wasn't an option. Please pick a valid option next time.\n");
}
}
You have a simple problem: the C language uses "call by value", so your phonebook() function gets a copy of the struct. Then the phonebook() function changes the copy, but the changes aren't saved anywhere.
The way you fix this: you have to make your phonebook() function take a pointer to a struct, and then it can use the pointer to modify the struct.
int phonebook(struct contact *pcontact, int use)
{
// ... stuff omitted ...
printf("What is the contact's first name?\n");
scanf("%s", pcontact->fname); // "fname" works as a pointer
printf("\nWhat is the contact's phone number?\n");
scanf("%d", &pcontact->pnumber); // must take address of integer "pnumber"
// ... rest of phonebook() omitted ...
// example of calling phonebook():
case 1:
phonebook(&p1, choice);
http://www.lysator.liu.se/c/bwk-tutor.html#pointers
You are passing person by value, not by reference, so phonebook is making changes to a copy of the contact struct.
Try
int phonebook(struct contact *person,int use);

Resources