1

In my class i been assigned to make a Library menu program which includes

a structure with bookname/author/price/issue date; then a menu with different options like addbook,display, search by author etc

i believe i got the basic idea of how to do it and i made a draft of it in codeblocks. but problem is code working but i cant get input/output of book name only (rest working i think) and i cant find the reason why. im a beginner in programming just been doing it for 2 month or so, so i would be very greatful if someone can point out whats wrong in my code.

Thanks in advance and here is my code>

#include<stdio.h>
#include<string.h>

int bookcount=0;
struct library{                                  
char name[100];
char author[100];
float price;
char date[20];
}str[100];

int main(){
    int i;
    menu();
    return 0;
}

int menu(){
    int choice,i;
    for(i=0;;i++){
        printf("\nWelcome to library menu.Please enter a choice from below-");
        printf("\n\nPress 1 to add book information\nPress 2 to Display book information\nPress 3 to search books by author name");
        printf("\nPress 4 to list the count of books\nPress 5 to find all the books for given price\nPress 0 for exit\nChoice=");
        scanf("%d",&choice);
    if(choice==0)
        break;
    else{
        switch(choice){
            case 1:
                addbook();
                break;
            case 2:
                display();
                break;
            case 3:
                searchbyauthor();
                break;
            case 4:
                listcount();
                break;
            case 5:
                findbyprice();
                break;
            default:
                printf("invalid input!\n");
        }
    }
}
return 0;
}


int addbook(){
    int n,i;
    printf("\nEnter number of books to add=");
    scanf("%d",&n);
    for(i=0;i<n;i++){
        printf("\nEnter book title=");
        gets(str[bookcount].name);
        printf("\nEnter book author=");
        gets(str[bookcount].author);
        printf("\nEnter book date=");
        gets(str[bookcount].date);
        printf("\nEnter book price=");
        scanf("%f",&str[bookcount].price);
        bookcount++;
}
return 0;
}

int display(){
    int i;
    for(i=0;i<bookcount;i++){
        printf("\nBook no %d name=",i+1);
        puts(str[i].name);
        printf("\nBook no %d author=",i+1);
        puts(str[i].author);
        printf("\nBook no %d issue date=",i+1);
        puts(str[i].date);
        printf("\nBook no %d price=%f",i+1,str[i].price);
    }
return 0;
}

int searchbyauthor(){
    char inp[100];
    int i;
    printf("\nEnter Author name to search=");
    gets(inp);

    for(i=0;i<bookcount;i++){
        if(strcmp(str[i].author,inp)==0)
            printf("\nBook name=%s",str[i].name);
    }

    return 0;
}

int listcount(){
    printf("\nnumber of books are =%d\n",bookcount);
    return 0;
}

int findbyprice(){
    float inp;
    int i;
    printf("\nEnter price to search=");
    scanf("%f",&inp);

    for(i=0;i<bookcount;i++){
        if(str[i].price==inp)
            printf("\nBook name=%s",str[i].name);
    }

    return 0;
}
  • 1
    `C` or `C++`? Please pick one. Your code is `C`. – Simon Kraemer Jul 13 '18 at 07:05
  • 2
    [Never use `gets()`...........](https://stackoverflow.com/q/30890696/2173917) – Sourav Ghosh Jul 13 '18 at 07:05
  • tx , i changed it to C. can u elaborate a bit plz with gets. – Rafiqul Echo Jul 13 '18 at 07:07
  • 1
    @RafiqulEcho Check the link. – Sourav Ghosh Jul 13 '18 at 07:07
  • Tx sourav , i see why gets is not used anymore. But i still cant find the reason why my code not working for book name only, while its working for others for example book author, date etc – Rafiqul Echo Jul 13 '18 at 07:17
  • 1
    Welcome to SO. Please always provide a [MCVE](https://stackoverflow.com/help/mcve). This includes to remove all the stuff that is not related to your problem like `searchbyauthor` etc. People who help for free do not really like to spend time on reading code that is not related at all. – Gerhardh Jul 13 '18 at 07:18
  • An alternative to `gets()` can be found [in this answer](https://stackoverflow.com/a/4023921/9381897). Consider creating a helping function that reads a string from `stdin` and assigning it to your struct's `char` fields. A bit off topic but a good exercise would be to dynamically allocate memory for struct's fields as you would be involved with pointers which are a very important part of the language. – leopal Jul 13 '18 at 12:57

1 Answers1

0

As you didn't post any input, I needed to find out that myself, just include sampling input and output next time:

1
1
name

Let's see what your program does with stdin at this point

scanf("%d",&choice); // in menu() in loop, choice := 1, ie add book
scanf("%d",&n); // in addbook(), n := 1, ie. 1 book
gets(str[bookcount].name); // in addbook in loop, this will be and should be ""

scanf() "consume and discard all leading whitespace characters", and newline is whitespace character. So this is what happens:

scanf("%d",&choice); // reads '1' from the input, and stops BEFORE newline
scanf("%d",&n); // discards newline and reads 1 from the input and stops before newline
gets(str[bookcount].name); // because newline is still in buffer and gets 
                           // stops at first newline, this will read empty string
// the next gets will read the `name` from stdin, as it wasn't read already

The fix is rather simple. Just scanf for lines scanf("%d\n",...); not for single variables.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • 1
    Tyvm for taking the time to answer Kamil Cuk. And i apologies for not giving input output as it is my first time posting in this site and in general about coding. This is actually very helpful explaination and i appritiate it. yesterday i randomly used getchar(); after scanf on my code and then it worked but i had idea what was the problem. Your explaination helped clear things a lot. – Rafiqul Echo Jul 14 '18 at 11:13