CodeBlanks Logo Icon CodeBlanks

Search and filter

  • C course
  • Intermediate
  • Lesson 68/116
  • 6 min

Write search and filtering with function pointers.

Search by title

To find a book by title, write find_by_title. Signature: Book *find_by_title(Library *lib, const char *title). Return type Book *; the found book's address or NULL.

Body: loop with for (int i = 0; i < lib->count; i++); check if (strcmp(lib->books[i].title, title) == 0) return &lib->books[i];. strcmp compares two strings; 0 means equal. After the loop, return NULL;. This pattern is the standard form of search functions in C; a pointer return carries both result and failure.

Filtering patterns

To filter a collection, use a predicate function: typedef int (*BookPred)(Book *);. BookPred is a function pointer taking a Book and returning int. A filter function takes this pointer and prints the matching books.

Example predicate: int is_borrowed(Book *b) { return b->borrowed; }. Inside filter loop with for and call the predicate with if (pred(&lib->books[i])). This is a real use of function pointers; the filter stays the same even when the predicate changes. This technique is C's equivalent of the strategy pattern in non-OO languages.

Practice Add find_by_title

Add Book *find_by_title(Library *lib, const char *title) to the existing code. Body: loop with for (int i = 0; i < lib->count; i++); check if (strcmp(lib->books[i].title, title) == 0) return &lib->books[i];; after the loop return NULL;. In main add a book, call Book *found = find_by_title(&lib, "C Tutorial"); and if (found) print_book(found);.

Starter code

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

typedef struct {
    char title[64];
    int year;
    int borrowed;
} Book;

typedef struct {
    char name[64];
    int id;
} Member;

typedef struct {
    Book books[10];
    int count;
} Library;

void library_init(Library *lib) {
    lib->count = 0;
}

void library_add(Library *lib, Book b) {
    lib->books[lib->count++] = b;
}

void print_book(Book *b) {
    printf("Book: %s (%d)\n", b->title, b->year);
}

int checkout(Book *b) {
    if (b->borrowed) return 0;
    b->borrowed = 1;
    return 1;
}

int return_book(Book *b) {
    if (!b->borrowed) return 0;
    b->borrowed = 0;
    return 1;
}

int main(void) {
    Library lib;
    library_init(&lib);
    Book b1 = {"C Tutorial", 2024, 0};
    library_add(&lib, b1);
    checkout(&lib.books[0]);
    printf("%d\n", lib.books[0].borrowed);
    return_book(&lib.books[0]);
    printf("%d\n", lib.books[0].borrowed);
    return 0;
}

// Write find_by_title function
// In main: find_by_title for "C Tutorial" and call print_book

Sample solution

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

typedef struct {
    char title[64];
    int year;
    int borrowed;
} Book;

typedef struct {
    char name[64];
    int id;
} Member;

typedef struct {
    Book books[10];
    int count;
} Library;

void library_init(Library *lib) {
    lib->count = 0;
}

void library_add(Library *lib, Book b) {
    lib->books[lib->count++] = b;
}

void print_book(Book *b) {
    printf("Book: %s (%d)\n", b->title, b->year);
}

int checkout(Book *b) {
    if (b->borrowed) return 0;
    b->borrowed = 1;
    return 1;
}

int return_book(Book *b) {
    if (!b->borrowed) return 0;
    b->borrowed = 0;
    return 1;
}

Book *find_by_title(Library *lib, const char *title) {
    for (int i = 0; i < lib->count; i++) {
        if (strcmp(lib->books[i].title, title) == 0) return &lib->books[i];
    }
    return NULL;
}

int main(void) {
    Library lib;
    library_init(&lib);
    Book b1 = {"C Tutorial", 2024, 0};
    library_add(&lib, b1);
    Book *found = find_by_title(&lib, "C Tutorial");
    if (found) print_book(found);
    return 0;
}

Expected output

Book: C Tutorial (2024)

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 Match search tools

Term Meaning
strcmp String comparison
Book * Return type
NULL Not found
lib->count Loop bound

2 What does find_by_title return when not found?

  • Empty Book
  • NULL Correct answer
  • 0
  • -1

Explanation: When not found it returns NULL; the caller checks for NULL.

3 Complete the strcmp comparison

Question
if (____(lib->books[i].title, title) == 0) return &lib->books[i];
Answer
if (strcmp(lib->books[i].title, title) == 0) return &lib->books[i];

Explanation: strcmp compares two strings; 0 means equal.

All lessons in Intermediate