Mètodes

42 (III): ft_printf, el printf propi

Recrear printf amb variadic arguments: formaters, amplades i la il·lusió de facilitat d'una funció que usem cada dia.

42 (III): ft_printf, el printf propi

Quan vas escriure el teu primer programa, algú et va dir que printf serveix per mostrar coses per pantalla. Ningú no explica com fa la màgia del format: com sap quan el %d és un enter i el %s una cadena. ft_printf és el projecte on això deixa de ser màgia: has de tornar a escriure printf tu mateix.

El problema

printf és una funció variàdica: accepta tants arguments com vulguis, i C no et diu quants ni de quin tipus són. L’única informació és la cadena de format, que has d’anar recorrent caràcter a caràcter: quan trobes un %, el següent caràcter et diu què cal imprimir. El meu entorn era el conjunt clàssic: %c per caràcters, %s per cadenes, %d i %i per enters, %u, %x i %X per sense signe i hexadecimal, %p per punters i el %% literal. I un detall que la documentació es salta: la funció ha de retornar el nombre total de caràcters impresos, no només mostrar-los.

Com el vaig abordar

Vaig separar el recorregut de la cadena de la impressió de cada tipus. Un bucle que detecta el % i una funció auxiliar per cada especificador: caràcter, cadena, enter, hexadecimal, punter. Cada auxiliar imprimeix i compta, i al final es suma el total. Els casos que més van sagnar van ser els que ningú prova: una cadena NULL que cal mostrar com (null), el valor mínim d’un enter amb signe, que no es pot invertir amb seguretat, i els punters nuls. A l’hora de provar, la tècnica més útil va ser comparar la sortida byte a byte amb el printf real: si el recompte de caràcters no quadra, alguna cosa està malament. El repositori, 42_ft_printf, va quedar ordenat en poques peces: la funció principal, dues capes d’utilitats i una capçalera.

Què en vaig treure

La lliçó gran és sobre stdarg.h i la manera com C passa arguments d’una llargària variable per la pila: quan no hi ha tipus, tot depèn que la cadena de format i els arguments passats quadren, i el compilador no t’avisarà si no és així. També vaig aprendre que les funcions quotidianes tenen molta enginyeria invisible: printf porta dècades d’optimitzacions i extensions, i encara que la meva versió només cobreix una part, ara quan l’escric sé exactament què passa a sota. I una cosa pràctica: des de llavors, ft_printf és la funció d’impressió de tots els meus projectes de 42. La caixa d’eines creix.