Sitemap

My own _printf: Why AI isn’t ready to replace us (yet)

5 min readApr 12, 2026

--

1. Context

Recreating printf from scratch is probably the biggest headache of the first year in C. It’s that project where you finally understand that printf isn't magic—it’s just a lot of parsing and variadic arguments. I built my version using a Jump Table (an array of structs) because I wanted to keep it modular and avoid a 500-line if/else mess.

2. My Focus: The Parsing Logic

I spent most of my time on the parsing part. It’s the “engine” of the function. If your pointer logic is off by just one character, the whole thing crashes or prints garbage. I wanted to see if an AI could actually follow my pointer movements or if it would just give me generic advice.

specifier array_of_struct[] = { /*array of struct with specifier char*/
{"c", print_char}, /*for a char*/
{"s", print_string},/*for a string*/
{"%", print_percent},/*for a percrent after another one*/
{"d", print_int},
{"i", print_int},
{NULL, NULL}
};

Deep Dive: The Parsing “Engine”

The parsing logic is where the real battle happens. In C, you don’t have high-level strings; you have a memory address and a cursor. My while (format[i]) loop is the heart of the function, and it has to switch between two very different states:

Literal State: Just printing what it sees.

Specifier State: Triggered by a %, where it must jump one character ahead, identify the type, call the right function, and then—this is the tricky part—resume the scan exactly where it left off.

I specifically wanted to see if the AI could follow this “jump” logic. When I find a %, I manually do i++ to check the next character. The AI flagged this as a potential "off-by-one" error. It thought I might be skipping a character or reading out of bounds.

Get Maxime Bernier’s stories in your inbox

Join Medium for free to get updates from this writer.

But here’s the thing: I knew my cursor was exactly where it needed to be. I had manually traced the pointer movement for every possible scenario:

  • _printf("%%") -> Does it print one % or two?
  • _printf("Hello %") -> Does it try to read format[i+1] when it's already at the end of the string?
  • _printf("Hello %y") -> Does it print the char after the % when it’s not a specifier.

3. The Prompt I used

I didn’t ask the AI to “fix” my code. I asked it to be a brutal reviewer. Here is what I sent:

“Hey, I’m looking for a code review on my _printf. I'm specifically worried about the format string parsing and how I'm handling the pointer increments. Can you audit the logic for edge cases (like a lone % at the end) without actually rewriting any of it? I want to find the bugs myself, just need a second pair of eyes on the logic."

4. What the AI flagged

The AI came back with a few points:

  • The “Magic Number” trap: It noticed I used j < 5 in my loop. To be honest, it’s right—it’s a lazy way to code. If I add a new specifier later, I'll definitely forget to update that number.
while (j < 5) /* we compare it with our array of struct*/
{
/*if %[] == specifier[j]*/
if (format[i] == array_of_struct[j].specifier[0])
{
counter += array_of_struct[j].f(args);
found = 1;
break;/*we call the function linked to it*/
}
j++;
}
  • The Index Confusion: It flagged my i++ right after the % as a potential bug, thinking I was skipping a character by mistake.
if (format[i] != '%') /* if the char is diff than a % */
{
_putchar(format[i]);
counter++;
}

else /*if there is a %, we check the char after*/
{
i++;

......
  • Handling big negative numbers: The AI noticed that I used an unsigned int to handle negative numbers. It’s a classic trap in C: the smallest possible negative number can't be converted back to a positive int without crashing the program. My code avoids this, and the AI picked up on that small but important detail.
 if (n < 0)/*if n is below 0, we had a - before*/
{
_putchar('-');
count++;
num = -n;
}

5. My take: Where the AI was actually wrong

This is the part where you see the limits of the tool. The AI told me my i++ (the one I use to look at the character immediately after the %) was an error. But it’s literally the opposite. If I don't do that i++, I stay stuck on the % and never reach the specifier (like the 's' or 'd'). The AI got confused by the flow and thought I was skipping data, which proves it doesn't always "read" the logic—it just looks for patterns.

Also, it lectured me about using recursion for printing numbers. Sure, in a perfect world, recursion uses stack space, but for a 10-digit number, it’s totally fine.

The “Gaslighting” AI: There was this one moment where the AI was convinced my pointer increment was wrong. I knew it was right, so I asked: “Are you sure about that?”. Instead of re-analyzing the logic, it just gave a vague answer.

6. Lessons Learned

Using AI as a reviewer is actually super useful, but you can’t turn your brain off.

  • The Good: The AI is amazing at catching the “dumb” stuff that makes you feel like an amateur: a missing semicolon at the end of a line, weird indentation that breaks the look of your code, or a random space that shouldn’t be there.
  • The Bad: This is where it gets tricky. AI struggles with original logic. It has been trained on millions of GitHub files, so it has a “template” in its head of what a printf should look like. If your logic is a bit different—even if it's perfectly valid—the AI starts to panic. It sees a pattern it doesn't recognize and starts hallucinating bugs that simply don't exist.

The “Are you sure about that?” Moment: The most frustrating part is the “gaslighting.” I had a specific moment where I challenged the AI on a pointer increment it flagged as an error. I asked, “Are you sure about that?” Instead of actually re-calculating, it just started looping. It gave me a vague answer that sounded professional but was technically wrong. It’s like it couldn’t admit it didn’t actually “understand” the math I was doing.

7. Conclusion

Don’t use AI to write your project — you’ll learn nothing and get caught. But using it as a “second pair of eyes” to find what you forgot? That’s a pro move. Just remember: you’re the dev, you decide which advice to keep. In low-level C, trust your own tests and your own logic more than the AI’s opinion.

--

--