As for scanf: I want it to either succeed in parsing all of the arguments, or fail, but in this case leave the file position unchanged (so random access is required on input). This would allow trying to parse with another call to scanf, but with a different format string. For lists involving an arbitrary number of items, provide a conversion specifier that leaves the input alone and returns success: this way you can iterate the list.
For example, these would be equivalent:
if (scanf(f, "%d %d %d", &a, &b, &c)) printf("Success!\n");
if (scanf(f, "%d %e", &a) && scanf(f, "%d %e", &b) && scanf(f, "%d", &c)) printf("Success!\n");
/* %e means more input expected, without it scanf fails if no EOF at that point */
I should be able to provide my own parsing functions in it: imagine a conversion specifier for JSON that returns a tree.The existence of sprintf and sscanf point to bad design: I should be able to open a block of memory as a FILE, which would make sprintf and sscanf redundant. Also I should be able to open some kind of block device: meaning the FILE has pointers to user provided read and write functions. With this I could printf and scanf to some indirect device such as an EEPROM.
We should be using scanf for the program's argument list. I mean the program should not get an array of pointers, but instead a FILE that contains the arguments. The memory layout is then abstracted. The pre-conversion of the command line to an array is totally unnecessary, only exists because libc's scanf sucks.
Arbitrary length strings could have been handled with FILEs..