dima

on software
Posts from blog by tag c:

The Pitfalls of Reading User Input in C: a Story About scanf and Stdin

I recently had to write a piece of C code that takes some input from stdin, ignores the newline, discards whatever exceeds the buffer, and does this repeatedly in a loop.

Knowing something about scanf syntax (man) I came up with this:

#include <stdio.h>

void take_input(void)
{
    char buf[20];
    printf("> ");
    scanf("%19[^\n]", buf);
    printf("input=`%s`\n", buf);
}

int main(void)
{
    for (int i = 0; i < 5; i++) {
        take_input();
    }

    return 0;
}

(Note: The original code used an infinite loop, but a simple for is enough to demonstrate the behavior.)

When I ran it, the result was surprising:

$ gcc -o main main.c
$ ./main
> hello world↵
input=`hello world`
> input=`hello world`
> input=`hello world`
> input=`hello world`
> input=`hello world`
$ █

It consumed the string once and printed the same value 5 times. Why?

Read more

Abstractions and Inheritance in C - Elegant Foot-Shooting

TL;DR https://github.com/ddoroshev/c-inheritance

Sometimes you want to abstract and generalize something in C code. For example, if you want to print the contents of a structure multiple times, you end up writing printf("%s %d %f\n", foo->bar, foo->baz, foo->boom) everywhere like a fool, and it intuitively seems that there should be a way to do foo->print(foo), and not just with foo, but with any structure.

Let's take an example: there is a guy with a first name and a last name, and there is a bird that has a name and an owner.

typedef struct Person Person;
struct Person {
    char *first_name;
    char *last_name;
};

typedef struct Bird Bird;
struct Bird {
    char *name;
    Person *owner;
};

To print information about these animals, a cunning C programmer would simply write two functions:

void Person_Print(Person *p) {
    printf("%s %s\n", p->first_name, p->last_name);
}

void Bird_Print(Bird *b) {
    printf("%s of %s %s\n", b->name, b->owner->first_name, b->owner->last_name);
}

And they would be right! But what if we have many such structures and our brains are corrupted by OOP?

Read more