0

I'm making a c program for a simple library but for some reason the program keeps crashing right on startup. Like there's a menu that is displayed but it doesn't even appear it just crashes. can any one help me?

struct library
{
    char name[50];
    int id;
    int qty;
}books[50],copy[50],delet[50],sort[50];
int i=0;
FILE *mybooks;

int main()
{
    int choice; char ans;
    int id;
    int qty;
    int s,o=0,j=0;
    char name[50];
    mybooks=fopen("D:\\mybooks.txt","r");
    if (mybooks == NULL) printf("Error. File not found.");
    else
    {
        while(!feof(mybooks))
        {
            fscanf(mybooks,"%[^\n] %d %d",books[i].name,&books[i].id,&books[i].qty);
            strcpy(copy[i].name,books[i].name);
            copy[i].id=books[i].id;
            copy[i].qty=books[i].qty;
            i++;
        }
        fclose(mybooks);
    }
    printf("Welcome to the Library.\n");
    do
    {

        printf("Please choose an option:\n");
        printf("1.Insert a book\n");
        printf("2.Delete a book\n");
        printf("3.Search a book by ID\n");
        printf("4.Search a book by name\n");
        printf("5.Display all books (sorted by name)\n");
        printf("6.Display all books (unsorted)\n");
        scanf("%d",&choice);
        switch (choice){
        case 1:
            printf("You will need to enter a name, ID, and quantity of the book.\n");
            printf("please enter book name:");
            fflush(stdin);
            fgets(name,sizeof name,stdin);
            printf("please enter book ID:");
            scanf("%d",&id);
            printf("please enter book quantity:");
            scanf("%d",&qty);
            InsertBook(name,id,qty);
            printf("your book has been added successfully\n");
            break;
        case 2:
            printf("Please enter book ID:");
            scanf("%d",&id);
            DeleteBook(id);
            printf("book successfully deleted.\n");
            break;
        case 3:
            printf("Please enter ID of Book:");
            scanf("%d",&id);
            s=LinearSearch(id,j);
            if (s>=0)
            {
                printf("Book Found.\n");
                printf("Name:%s",books[s].name);
                printf("ID:%d\n",books[s].id);
                printf("Quantity:%d\n",books[s].qty);
            }
            else
                printf("Sorry, the book doesn't exist.\n");
            break;
        case 4:
            printf("Please enter name of book:");
            fflush(stdin);
            gets(name);
            sorting();
            s=BinarySearch(name,0,i);
            printf("Book Found.\n");
            printf("ID:%d\n",sort[s].id);
            printf("Quantity:%d\n",sort[s].qty);
            break;
        case 5:
            sorting();
            while (o<i);
            {
                printf("%s\n",sort[o].name);
                o++;
            }
            printf("\n");
            break;
        case 6:
            while(o<i)
            {
                printf("%s",books[o].name);
                o++;
            }
            break;
        default:
            printf("Invalid Choice. Please try again.\n");
            break;
        }
        printf("do you want to choose another option?(y/n)  ");
        scanf(" %c",&ans);
    }while(ans == 'y');
}

(I'm using functions for the library but I don't think they are causing any problem since i didn't call them yet.) edited the question to add the structure

  • 4
    See [Why is `while(!feof(fp))` always wrong?](https://stackoverflow.com/questions/5431941) – user3386109 Jun 03 '20 at 19:18
  • 4
    Also see [mcve] – user3386109 Jun 03 '20 at 19:20
  • 1
    You ignore the return value of scanf() and friends at your own risk. It is usually useful help with debugging. Please report all the returned values in case of failure. Note: The return values, NOT the scanned values. – Yunnosch Jun 03 '20 at 19:25
  • 1
    You have done no checking on array bounds while reading the file data. Even if you think you have defined *exactly* the right size of array for the unshown `books[]` there is one record extra due to the incorrect use of `feof`. Moreover there are other essential checks not made . `%[^\n]` will read right past the next two `%d` data items expected if they are on the same line and you won't know because you don't check the return value of `fscanf` ***and*** it probably breaks the string array size which is unrestricted: `%[^\n]` should be `%49[^\n]` or whatever is 1 less than the array length. – Weather Vane Jun 03 '20 at 19:26
  • How does this compile? `copy` and `books` aren't defined. – Brecht Sanders Jun 03 '20 at 19:27
  • @BrechtSanders So you agree with comment by user33861097? – Yunnosch Jun 03 '20 at 19:28
  • @Yunnosch which comment do you mean? – Brecht Sanders Jun 03 '20 at 19:41
  • Ah there are two and I misspelled the user name, sorry. I mean the one asking for an MRE, which is what you seem to also be asking. It is a more efficient way to hint OPs, because asking for specific missing details like you did all too often results in ONLY them being added - often in a comment. I ask just for the case that you do not know the trick of using `[mre]` in a comment or maybe even are unaware of the whole MRE concept. @BrechtSanders – Yunnosch Jun 03 '20 at 19:44
  • 1
    `if (fscanf(mybooks, "%[^\n]%d%d", books[i].name, &books[i].id, &books[i].qty) != 3) fprintf(stderr, "bad data on line %d\n", i);` – pmg Jun 03 '20 at 20:03
  • 2
    Also, [never use gets()](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used), it is deprecated because it can cause buffer overflows. – Marcelo Roberto Jimenez Jun 03 '20 at 20:07
  • the posted code does not compile! Compiling results in several messages about 'implicit declaration of functions (mostly due to missing `#include` statements for the needed header files. ) Also several warning and error messages are output by the compiler. Please post a [mcve] so we can reproduce the problem and help you debug it. – user3629249 Jun 06 '20 at 05:01
  • regarding: `if (mybooks == NULL) printf("Error. File not found.");` Error messages should be output to `stderr`, not `stdout` and when the error indication is from a C library function, should also output the text reason the system thinks the error occurred. The function: `perror( "error message" )` is made for that purpose. – user3629249 Jun 06 '20 at 05:05
  • when the call to `fopen()` fails, the next thing that is output (after the error message) is: `printf("Welcome to the Library.\n");` then a menu. This is not valid logic. Suggest follow the error message with: `exit( EXIT_FAILURE );` note: `exit()` and `EXIT_FAILURE` are exposed via the header file: `stdlib.h` – user3629249 Jun 06 '20 at 05:07
  • regarding: `fflush(stdin);` the function: `fflush()` is ONLY for output file streams and the C standard specifically states that using `fflush()` in an input stream is undefined behavior. So, should not use that statement (although visual studio allows it) Suggest: `int ch; while( (ch = getchar() ) != EOF && ch != '\n' ){;}` – user3629249 Jun 06 '20 at 05:11
  • regarding: `printf("Please choose an option:\n"); printf("1.Insert a book\n"); printf("2.Delete a book\n"); printf("3.Search a book by ID\n"); printf("4.Search a book by name\n"); printf("5.Display all books (sorted by name)\n"); printf("6.Display all books (unsorted)\n");` the function: `printf()` is expensive in CPU cycles. Suggest `printf( "Please choose an option:\n" newline "1.Insert a book\n"; newline ... );` – user3629249 Jun 06 '20 at 05:15
  • the posted code is calling several functions that are not posted! We are unable to guess as to the contents of those function. At the very least, post a prototype for each of those functions – user3629249 Jun 06 '20 at 05:17
  • Please post a few lines from the input file, especially as the code is crashing while trying to read that input file into an array – user3629249 Jun 06 '20 at 05:21
  • regarding: `while(!feof(mybooks)) { fscanf(mybooks,"%[^\n] %d %d",books[i].name,&books[i].id,&books[i].qty);` this would be much better written as: `while( fscanf( mybooks, "%49[^\n] %d %d", books[i].name, &books[i].id, &books[i].qty ) ==3 ) {` – user3629249 Jun 06 '20 at 05:26

1 Answers1

2

You have tested an end of file condition before performing any i/o on the input file. And then, when you perform the i/o with fscanf(), you did not test the result to see if the variables were successfully read.

What is happening is that scanf() is probably failing and you do not reach the end of the loop, i.e., the EOF condition. You get stuck in there until one of your assignments (strcpy(copy[i].name,books[i].name);, copy[i].id=books[i].id; or copy[i].qty=books[i].qty;) will finally cause an overflow.

To verify this, run the code in a debugger.

Using fscanf() is very tricky, always test it thoroughly.