Modification history:
- 2012-12-19 - First version.
- 2012-12-29 - Fixed loop nesting (loops can nest up to 10 levels deep) and incorrect brainf*ck code due to copy-and-paste mistake.
- 2013-01-04 - Added nested loop example.
Here is a C++ program which translates Brainf*ck into C. The code it produces is pretty ugly, but it works.
Translator source code:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 
 | #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#define BF_BUFFER_MIN     "0"
#define BF_BUFFER_MAX "32768"
static const char* BF_HEAD =  "#include <stdint.h>\n"
                              "#include <stdio.h>\n"
                              "\n"
                              "#define BUFFER_MIN " BF_BUFFER_MIN "\n"
                              "#define BUFFER_MAX " BF_BUFFER_MAX "\n"
                              "\n"
                              "int main(void)\n"
                              "{\n"
                              "    static uint8_t buffer[BUFFER_MAX];\n"
                              "    static uint32_t index = 0;\n";
static const char* BF_IPTR =  "    if (index < BUFFER_MAX)\n"
                              "        ++index;\n"
                              "    else\n"
                              "        index = 0;\n";
static const char* BF_DPTR =  "    if (index > BUFFER_MIN)\n"
                              "        --index;\n"
                              "    else\n"
                              "        index = BUFFER_MAX - 1;\n";
static const char* BF_IVAL =  "    ++buffer[index];\n";
static const char* BF_DVAL =  "    --buffer[index];\n";
static const char* BF_PUTC =  "    putchar(buffer[index]);\n";
static const char* BF_GETC =  "    buffer[index] = getchar();\n";
static const char* BF_LOOP1 = "L$a:\n"
                              "    if (buffer[index] == 0)\n"
                              "        goto L$b;\n";
static const char* BF_LOOP2 = "L$b:\n"
                              "    if (buffer[index] != 0)\n"
                              "        goto L$a;\n";
static const char* BF_TAIL =  "    return 0;\n"
                              "}\n";
static std::string replace_all(const std::string& a, const std::string& b, std::string s)
{
    size_t pos = 0;
    while ((pos = s.find(a)) != std::string::npos)
        s.replace(pos, a.size(), b);
    return s;
}
static std::string chars2string(std::vector <char> chars)
{
    std::stringstream sstream;
    for (char c : chars)
        sstream << c;
    return sstream.str();
}
int main()
{
    int c, label = 1, nest = 0;
    std::cout << BF_HEAD;
    while ((c = std::cin.get())) {
        if (std::cin.eof())
            break;
        switch (c) {
        case '>': std::cout << BF_IPTR; break;
        case '<': std::cout << BF_DPTR; break;
        case '+': std::cout << BF_IVAL; break;
        case '-': std::cout << BF_DVAL; break;
        case '.': std::cout << BF_PUTC; break;
        case ',': std::cout << BF_GETC; break;
        case '[':
            std::cout << replace_all("$", chars2string({ char(label + '0'),
                                            char(nest + '0') }), BF_LOOP1);
            ++nest;
            break;
        case ']':
            --nest;
            std::cout << replace_all("$", chars2string({ char(label + '0'),
                                            char(nest + '0') }), BF_LOOP2);
            if (!(nest))
                ++label;
            break;
        default:
            break;
        }
    }
    std::cout << BF_TAIL << std::endl;
    return 0;
}
 | 
Example input:
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Output of translator:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 
 | #include <stdint.h>
#include <stdio.h>
#define BUFFER_MIN 0
#define BUFFER_MAX 32768
int main(void)
{
    static uint8_t buffer[BUFFER_MAX];
    static uint32_t index = 0;
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
L10a:
    if (buffer[index] == 0)
        goto L10b;
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    if (index > BUFFER_MIN)
        --index;
    else
        index = BUFFER_MAX - 1;
    if (index > BUFFER_MIN)
        --index;
    else
        index = BUFFER_MAX - 1;
    if (index > BUFFER_MIN)
        --index;
    else
        index = BUFFER_MAX - 1;
    if (index > BUFFER_MIN)
        --index;
    else
        index = BUFFER_MAX - 1;
    --buffer[index];
L10b:
    if (buffer[index] != 0)
        goto L10a;
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    ++buffer[index];
    putchar(buffer[index]);
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    putchar(buffer[index]);
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    putchar(buffer[index]);
    putchar(buffer[index]);
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    putchar(buffer[index]);
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    ++buffer[index];
    putchar(buffer[index]);
    if (index > BUFFER_MIN)
        --index;
    else
        index = BUFFER_MAX - 1;
    if (index > BUFFER_MIN)
        --index;
    else
        index = BUFFER_MAX - 1;
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    putchar(buffer[index]);
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    putchar(buffer[index]);
    ++buffer[index];
    ++buffer[index];
    ++buffer[index];
    putchar(buffer[index]);
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    putchar(buffer[index]);
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    --buffer[index];
    putchar(buffer[index]);
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    ++buffer[index];
    putchar(buffer[index]);
    if (index < BUFFER_MAX)
        ++index;
    else
        index = 0;
    putchar(buffer[index]);
    return 0;
}
 | 
Output of translated program:
Hello World!
Example with nested loops:
[[[[[[[[]]]]]]]]
Output of translator:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 
 | #include <stdint.h>
#include <stdio.h>
#define BUFFER_MIN 0
#define BUFFER_MAX 32768
int main(void)
{
    static uint8_t buffer[BUFFER_MAX];
    static uint32_t index = 0;
L10a:
    if (buffer[index] == 0)
        goto L10b;
L11a:
    if (buffer[index] == 0)
        goto L11b;
L12a:
    if (buffer[index] == 0)
        goto L12b;
L13a:
    if (buffer[index] == 0)
        goto L13b;
L14a:
    if (buffer[index] == 0)
        goto L14b;
L15a:
    if (buffer[index] == 0)
        goto L15b;
L16a:
    if (buffer[index] == 0)
        goto L16b;
L17a:
    if (buffer[index] == 0)
        goto L17b;
L18a:
    if (buffer[index] == 0)
        goto L18b;
L19a:
    if (buffer[index] == 0)
        goto L19b;
L19b:
    if (buffer[index] != 0)
        goto L19a;
L18b:
    if (buffer[index] != 0)
        goto L18a;
L17b:
    if (buffer[index] != 0)
        goto L17a;
L16b:
    if (buffer[index] != 0)
        goto L16a;
L15b:
    if (buffer[index] != 0)
        goto L15a;
L14b:
    if (buffer[index] != 0)
        goto L14a;
L13b:
    if (buffer[index] != 0)
        goto L13a;
L12b:
    if (buffer[index] != 0)
        goto L12a;
L11b:
    if (buffer[index] != 0)
        goto L11a;
L10b:
    if (buffer[index] != 0)
        goto L10a;
    return 0;
}
 |