I wanted to learn how to work with file I/O properly so i've found an assignment in my college papers and decided to write it.

So here it is.

    //Write a C program which reads data about books and inputs them into a file named books.txt, like this:
    //
    //book_name#author_name#page_num#code#is_lent#
    //
    //book_name is an array of a maximum of 50 characters, author_name is an array of a maximum of 50 characters,
    //page_num is an integer, code is an integer, is_lent is an integer of interval [0, 1] where 1
    //means that the book is lent, and 0 that it isn't.
    //Program creates a new file if it exists or opens an existing one and appends new
    //data on the end. Input ends when the book name is 'x'.
    //Print the contents of the file.

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

    /*   Function prototypes    */
    void buff_clr( void );
    void write_to_file( FILE *fp );
    void read_from_file( FILE *fp );
    void remove_newline( char *string );

    int main()
    {
        FILE *fp;

        fp = fopen( "Books.txt" , "a+" );

        if( fp == NULL )
        {
            fprintf( stderr , "Error opening file" );
            exit( 1 );
        }

        write_to_file( fp );
        read_from_file( fp );
        fclose( fp );
        return 0;
    }

    /*   Removes newline from strings caused by fgets()    */
    void remove_newline(char *string)
    {
        char *ptr;

        if ( ( ptr = strchr( string , '\n' ) ) != NULL )
          *ptr = '\0';
    }

    /*   Picks up left over characters from the buffer in case there are any    */
    void buff_clr(void)
    {
        char garbage;
        do
        {
            garbage = getchar();
        }while( garbage != '\n' );
    }

    /*   Requests input and writes it to file   */
    void write_to_file( FILE *fp )
    {
        struct book_s
        {
            char book_title[50];
            char author_name[50];
            unsigned int page_num;
            unsigned int code;
            unsigned int is_lent;
        }book;

        while(1)
        {
            /*          Data input into struct        */
            printf( "Book title: " );

            fgets( book.book_title , 50 , stdin );

            remove_newline(book.book_title);

            if( strcmp( book.book_title , "x") == 0 )
            {
                break;
            }

            printf( "Name of the author: ");

            fgets( book.author_name , 50 , stdin );

            remove_newline(book.author_name);

            printf( "Number of pages: " );

            scanf( "%d" , &book.page_num );

            printf( "Book code: " );

            scanf( "%d" , &book.code );

            do
            {
                printf( "Is book lent(1 = yes , 0 = no):" );

                scanf( "%d" , &book.is_lent );
            }while(book.is_lent > 1);

            /*           Data input into file          */

            fprintf( fp , "%s#%s#%d#%d#%d#\n", book.book_title , book.author_name , book.page_num , book.code , book.is_lent );

            printf( "\n\n" );

            buff_clr(); //Using this here because without it a '\n' sneaks into book title on next iteration for some reason
        }
    }

    /*  Reads the file we've just written to    */
    void read_from_file( FILE *fp )
    {
        struct book_s
        {
            char book_title[50];
            char author_name[50];
            char page_num[5];
            char code[20];
            char is_lent[1];
        }book;

        char line[BUFSIZ];

        //Rewind to start of file
        fseek(fp, 0, SEEK_SET);

        while( fgets( line , sizeof(line) , fp ) != NULL )
        {
            strcpy( book.book_title , strtok( line , "#" ) );
            strcpy( book.author_name , strtok( NULL , "#" ) );
            strcpy( book.page_num , strtok( NULL , "#" ) );
            strcpy( book.code , strtok( NULL , "#" ) );
            strcpy( book.is_lent , strtok( NULL , "#" ) );

            printf( "\nBook title: %s", book.book_title );
            printf( "\nName of the author: %s", book.author_name );
            printf( "\nPage num: %s", book.page_num );
            printf( "\nBook code: %s", book.code );
            printf( "\nIs book lent: %s", book.is_lent );
            printf( "\n\n" );
        }
    }

Now this all works within the confines of the assigment. But what i am wondering is is my code too long? Could this have been written any shorter? Could this have been written any better? Did i miss anything? Are there any mistakes?

A few things to note. I know i don't really need structs but i had an idea of using them to create arrays of data and then print them one by one but i decided to scrap that idea since the only thing i'd accomplish is more lines of code and more memory wasted, but i liked the look of the struct so i kept it.

Oh and is there a way i could read all the data in their rightful forms without having to read them all as a string and then parse them and then convert them (i didn't convert integers here since i didn't really need to)? I know i can't use fscanf which would read strings until the whitespace character so it would try to gobble the whole line up since there aren't any.

Also what if i had to read multiple lines of varying lengths and file types?
for example if instead of `book_name#author_name#page_num#code#is_lent#`
being all one line what if it was

`book_name#page_num#`

`author_name#code#is_lent#`

What would be the ways of reading such input?