Now we're going to play with processing input. Brainfuck allows
you to read a byte as input and store it in the byte at the pointer. This
means that entering 123
will be read as the byte-values 49,
50 & 51.
"Well that's really convienent..."
Hey, I didn't design the language.
Let's write a program which reads in three characters and writes them out
,.,.,.This is a no-brainer: read a character, then write a character. Now something a bit more 'robust':
>+[>,] <[<] >>[.>]Which is equivalent to:
p++; a[p]++; while (a[p]) { p++; a[p] = getchar(); } p--; while (a[p]) { p--; } p += 2; while (a[p]) { putchar(a[p]); p++; }Let's break it down. First:
>+[>,]This increments
p
, leaving a[0]
equal to zero.
it then increments a[1]
and enters a loop. a[1]
has to be non-zero in order for the loop to execute. Within the loop, we
increment p
and read and store a byte in a[p]
.
This loop continues until we read in a null leaving a[p]
equal
to zero after the read. The result is consecutive entries in a[]
for each character read. This of course limits what we can read in to the
maximum array size of 30000 characters. Next:
<[<]This 'rewinds' back to the beginning, stopping when
p
equals
zero. This is why a[0]
was left equal to zero. And finally:
>>[.>]
p
gets incremented twice to skip a[p]
which equals
zero and a[1]
which equals one from our input loop. We enter a
loop, outputting a character and incrementing p
until
a[p]
equals zero.
Now, this can be done in a simpler way which is not contstrained by the maximum array size:
+[,.]The logic here is pretty simple: increment
a[0]
so we can
enter a loop. Once in the loop, read a character and write it out.
Now, all the above work fine for redirecting input from a file: when the
end of file is reached, the ,
instruction reads a null, storing
a zero in the byte under the pointer. This is not the case with reading
input from he keyboard. Most Brainfuck implementations use some
form a getchar()
to implement the ,
instruction.
This means that at the first ,
the program will wait for you
to type in some characters follower by 'enter'. Each ,
will
fetch a character from the string entered, including the 'enter' you pressed
(which it reads as an ASCII 13). If your program is going to process
keyboard input, you need to take this into consideration.
Here is an example which reads a string from the keyboard and prints it out in reverse order:
+[->,----------]<[+++++++++++.<]Which is equivalent to:
p++; while (a[p]) { a[p]--; p++; a[p] = getchar(); a[p] -= 10; } p--; while (a[p]) { a[p] += 11; putchar(a[p]); p--; }We prime the read loop (
+[->,----------]
) as in the previous
example. Once in the loop, we decrement a[p]
(on the first
pass of the loop, this resets a[0]
to zero, providing the
stop condition for the output loop), increment p
and read
and store a byte at a[p]
. We then subtract ten: if
a[p]
equals zero after this, then we have read a carrage
return and we exit the read loop. If not, we loop back around and do
it all over again.
The output loop (<[+++++++++++.<]
) is pretty straight forward.
We got to this point because the last character read in had a value of
ten and after subtracting ten from it, left the byte at the pointer equal
to zero, thus breaking out of the read loop. So, we decrement p
to get us back to the last character and enter a loop. We add eleven to
the byte at the pointer (ten from the carrage-return check plus one for the
decrement when the read loop starts again), print out the character and
decrement p
, moving us back down the array until we hit
a[0]
which equals zero and drops us out of the loop.
"Tell me again why I'm doing this?"
Why, for the sheer joy one gets from the challenge!
Click here and we'll look at some ways of doing things in Brainfuck.
Home | Introduction | First Program | Input Processing | Building Blocks | Resources | bf2pl