How it works:
The first three characters are all data and are not executed. They are a newline (10), a zero (48), and a DC3 (19).
Point b at the "0" character. Note that a is still pointing at the newline character.
Read the first character of input.
Subtract what b is pointing to (the "0") from the first digit.
Point b at the DC3 character, which has value 19
Jump to position 19+3=22 if the c is pointing to anything other than zero. This would happen if the first digit of the number was anything other than "0". Otherwise...
Move c on top of the "1" at the end of the program and print it.
b is still pointing at 19, so we add 19 to the instruction pointer, jumping to the "1" at the end of the program, causing the program to halt after one more cycle. (The extra space is ignored, but we need it there to position this instruction so that the instruction pointer jumps beyond the "]" at the end of the program. If we don't do this, we will enter the loop at the end, and print an extraneous semicolon whenever 0 is input.)
This is position 22, so we jump here whenever the number didn't start with "0". We move b back to point at the "0".
Add the 48 back to the first digit of the number, restoring it to its proper character value.
Subtract the newline from the digit.
If it's not zero, restore it to its original value and print it.
Repeat reading digits, comparing them with newline, and printing them until newline is seen.
Data. Ignored. Program halts.