Main answer
scanf() no analogue to the printf() * format specifier.
In Programming Practices , Kernigan and Pike recommend using snprintf() to create a format string:
size_t sz = 64; char format[32]; snprintf(format, sizeof(format), "%%%zus", sz); if (scanf(format, buffer) != 1) { …oops… }
Additional Information
Updating the example to the full function:
int read_name(FILE *fp, char *buffer, size_t bufsiz) { char format[16]; snprintf(format, sizeof(format), "%%%zus", bufsiz - 1); return fscanf(fp, format, buffer); }
This emphasizes that the size in the format specification is smaller than the size of the buffer (this is the number of non-zero characters that can be saved, not counting the terminating zero). Note that this is different from fgets() , where the size (a int , by the way, is not a size_t ) - this is the size of the buffer, and not one less. There are several ways to improve a function, but it shows a point. (You can replace s in the format [^\n] if that is what you want.)
Also, as Tim Hour noted in the comments , if you want (the rest of) the input line, you are usually better off using fgets() to read the line, but remember that it includes a new line in its output (while %63[^\n] leaves a newline for reading by the next I / O operation). For a more general scan (for example, 2 or 3 lines) this method might be better; especially if they are used with fgets() or getline() and then sscanf() to parse the input.
In addition, the TR 24731-1 secure access functions implemented by Microsoft (more or less) and standardized in Appendix K of ISO / IEC 9899-2011 (C11 standard) require a certain length:
if (scanf_s("%[^\n]", buffer, sizeof(buffer)) != 1) ...oops...
This avoids buffer overflows, but probably generates an error if the input is too long. The size can / should be specified in the format string, as before:
if (scanf_s("%63[^\n]", buffer, sizeof(buffer)) != 1) ...oops... if (scanf_s(format, buffer, sizeof(buffer)) != 1) ...oops...
Note that a warning (from some compilers under some flag sets) about a "variable format string" should be ignored or suppressed for the code using the generated format string.