There is only one expansion during
printf; that means any strings passed to
printf except the format strings will be printed verbatim (if at all). That is actually a good thing, because otherwise, it leaves a huge security hole.
The security risk relates to the fact that the format string and the parameter list have to correspond. That means, if an unwanted
% makes it to the format string, you will get in trouble:
fgets(ch, 50, stdin);
If the user supplies eg.
%p %p %p %p, he will be reading data stored on the stack (like the return address and so on), if he supplies
%s %s %s, he'll likely crash the program. If he supplies
%n, he'll overwrite some data on the stack.
That said, you can just compute the format string if you want:
char format_prototype="My name is %s";
snprintf(ch, 49, "%s", format_prototype);