Eine conversion specification (d.h. das was mit % anfängt) hat folgendes Format:
%<*><Width><Length><CS>.
Alle Teile außer <CS> sind optional.
<*> ist entweder * (es wird Eingabe gelesen, aber nicht der Variablen zugewiesen) oder nicht vorhanden.<Width> ist eine Zahl die die Anzahl der maximal zu lesenden Zeichen angibt.<Length> gibt vereinfacht ausgedrückt an, wieviel Speicher zur Verfügung steht, um die eingelesenen Daten zu speichern.<CS> ist der conversion specifier. Er gibt an, wie die eingelesenen Zeichen interpretiert weden sollen.
Zu den bekannteren conversion specifiern gehören d (die Zeichen werden als die Ziffern einer ganzen Zahl in Dezimaldarstellung aufgefasst) und s (die Zeichen werden als Zeichen einer Zeichenkette aufgefasst).
Aber auch [ ist ein conversion specifier. Er funktioniert genau so wie s, außer das angegeben werden kann, welche Zeichen gelesen werden können. Insbesondere werden die gelesenen Zeichen als Zeichen einer Zeichenkette aufgefasst und nicht als Ziffern einer Zahl. Das d am Ende von %[1-2]d ist nicht Bestandteil der conversion specification.
Es wäre nett von deinem Compiler gewesen, wenn er dich gewarnt hätte, dass %[ ein char* erwartet aber wegen int anzahl ein int* bekommen hat.
Weitere Details findest du im Abschnitt 7.23.6.2 des Entwurfs zum ISO Standard 9899:2023 Programming languages — C ab Seite 336.