read.c

DownloadView Raw

/**
 * read.c
 *
 * A simple program that uses the read(2) system call to read a file and count
 * up the number of ASCII zeros it finds. Important to note: there is no
 * guarantee that read() will return the requested number of bytes (BUF_SZ in
 * this case), so if your program expects a particular number of bytes you will
 * need to add another loop that ensures the read is complete.
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUF_SZ 128

#ifndef DEBUG
#define DEBUG 1
#endif

#define LOG(fmt, ...) \
    do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
            __LINE__, __func__, __VA_ARGS__); } while (0)

int main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <file>\n", argv[0]);
        return EXIT_FAILURE;
    }

    int fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open");
        return EXIT_FAILURE;
    }

    unsigned int zero_count = 0;
    char buf[BUF_SZ];
    ssize_t read_sz;
    while ((read_sz = read(fd, buf, BUF_SZ)) > 0) {
        LOG("Read size: %zu\n", read_sz);
        int i;
        for (i = 0; i < read_sz; ++i) {
            /* 48 is ASCII for '0' */
            if (buf[i] == 48) {
                zero_count++;
            }
        }
    }

    close(fd);

    if (read_sz == -1) {
        perror("read");
        return EXIT_FAILURE;
    }

    printf("Finished. Zeros = %d\n", zero_count);
    return 0;
}