sprintf 格式 - u 前三个 '%%%' 和 n 前两个 '%%'?

sprintf formatting - Three '%%%' before u and two '%%' before n?

在小组作业中,我们必须读取仅包含(小)字母 a-z 且字符的最大长度为 255 的输入。我想检查一下getchar 和 ASCII,但是我的搭档找到了使用 sprintf 和 scanf 的解决方案,我不是很明白:

#include <stdio.h>

int main() {

int result = 0;

unsigned int length = 255;
char input[257];

result = readInput(input, &length);

return 1;
}

int readInput(char *output, int *length) {

char format_pattern[15]; 
sprintf(format_pattern, "%%%u[^\n]%%n", *length); 

printf("Max allowed length is %d\n",*length);

scanf(format_pattern, output, length);

printf("Input length is %d\n",*length);

return 1;

}

输出: Max allowed length is 255 testinput Input length is 9

sprintf 和 scanf 中的格式模式是如何工作的? 特别是 u 之前的三个 %%%n 之前的两个 %% - 我尝试将其更改为 %u[^\n]%n 因为两个 ## 会逃脱' %´,但后来我收到一个错误,所以他们必须在那里。

我唯一想到的是:

我在谷歌上搜索了很多,但没有找到类似的例子 - 有人可以帮助我吗?

假设 x 是一个(足够大的)字符数组

sprintf(x, "%%"); // put a single % (and '[=10=]') in x
sprintf(x, "%u", 8); // put 8 (and '[=10=]') in x

sprintf(x, "%%%u", 8); // put %8 (and '[=10=]') in x

您的合作伙伴正在使用 sprintf()scanf() 动态创建格式字符串。这有点棘手,因为 printfscanf 函数主要使用相同的格式化语言。动态格式创建的原因似乎是在格式中插入可配置的字段宽度。这很聪明,但过于复杂且完全没有必要。

How does the format pattern in sprintf and scanf work? Especially the three %%% before u and the two %% before n

%%%u实际上是两个指令。第一个 %% 导致 printf 发出单个 % 字符,然后剩下 %u,我想你已经认出了。同样,%%n 一个 指令(%%,如上所述)加上文字 'n' 字符,按原样发出。整个 sprintf 调用准备了一个类似于 "%255[^\n]%n".

的格式字符串

那么,生成的格式如何与 scanf 一起使用?您可能应该阅读它的文档,随处可见,例如 here。那个恰好是针对 GLIBC 实现的,但是您没有使用任何非标准的东西,因此它应该解释您需要了解的有关您的特定格式的所有信息。具体来说,您费心介绍的 255 是由 [^\n] 描述的 "scanset" 中的字符组成的字段的最大字段宽度——除换行符外的每个字符。 %n 不消耗任何输入;相反,它存储了该 scanf 调用到目前为止读取的字符数。

出于您的目的,我认为绝对没有理由动态生成 scanf 格式。您 给定了 最大字段宽度,因此您不妨在文字格式字符串中使用它。即使您想要在运行时指定最大字段宽度,scanf() 也有比动态编写格式字符串更好的机制,包括将需要的字段宽度作为参数传递。

额外提示:您发布的代码在使用 *lengthprintf 中的 length 方面混淆不清和 scanf 个电话。在你想输出它的值的地方,你必须传递值(length)。在你想要scanf修改值的地方,你必须传递应该存储新值的地址(*length)。