EdPellesC99
Of course, if you want to be totally sure, you could write your own routines for processing your particular input data using fgets() approach, and in fact, that's what is often done in production code, but it's not really necessary at this point. Frankly speaking, there is no "silver bullet" as you put it. Additionally, when one talks about buffer, it could be an internal buffer as one that is declared being a char array, or otherwise an external system buffer. When scanf() is called with an "%s" parameter it is about to write in an internal buffer you specify, and that's when a buffer overrun may occur. However, when you're reading a number with scanf() you are virtually safe from such an occasion (given proper matching argument). So, scanf with "%lf" may be considered safe, and "%10lf" even safer (I don't quite remember is result defined or not taking "666666666666666666666666666"-like input in the first case, but it surely shouldn't make any security vulnerabilities).
Talking about external buffer, that's where your data gets in the first place. scanf() will read your input from this buffer until approaching the first symbol that cannot be understood given this format specifier. For example, if you have the "%d" specifier, it would read first three symbols of "123fg" string, but leave the others ("fg") staying there in the buffer. When you try to use scanf() again for doing a similar task it'd be forever stuck unable to read anything further. So, for preventing such an occasions, code snippet suggested above by me may be used. As I said, it meant to go right after any call to scanf(). Its sole puprose is to read and discard any input items remaining in system buffer until encountering a newline.