你的陈述
char charPin[] = ("PIN%d",pin);
正在尝试使用表达式("PIN%d",pin) 初始化一个未指定长度的char 数组。该表达式看起来像 Pythonesque,但它在 C 中的语法上是有效的:括号围绕涉及逗号 (,) 运算符的表达式执行它们的普通分组功能。在实际允许该表达式的上下文中进行评估,结果将具有与pin 相同的类型和值。这根本不是您想要的,幸运的是,问题是编译器拒绝的类型,而不是编译器生成代码以执行您实际告诉它执行的意外事情的类型。
char 数组的初始化程序可以采用以下两种形式之一:
- 字符串或 UTF-8 文字,或
- 用大括号括起来的单个元素数组。
这些都不适合您的目的,因此您必须将所需内容与声明分开来填充数组。此外,这意味着您必须为数组声明一个明确的大小。您需要为文本部分(您知道其大小)、整数部分(其大小是可变的,在限制内)和单字节字符串终止符留出空间。
如果您愿意做出非常合理的假设,即 pin 的数据类型 (int?) 不超过 64 位,那么 20 个字符就足够了,最多可能有 19 个十进制数字加上一个符号,因此 24 个字符对于整个字符串应该足够了。通常最好在代码中避免使用幻数,因此您可以像这样声明 charPin:
#define PIN_BUFFER_SIZE 24
// ...
char charPin[PIN_BUFFER_SIZE];
有几种方法可以填充数组内容,但最直接的方法是使用sprintf() 或snprintf()。假设我们对大小计算并不完全有信心,或者文本部分是可变的。然后,我们可能会在charPin 中声明比我们认为需要的更多的空间,但最终我们要确保我们不会覆盖数组的边界。 snprintf() 就是为此目的:
int result = snprintf(charPin, PIN_BUFFER_SIZE, "PIN%d", pin);
这是基本答案,但细心的程序员不会就此罢休。假设我们希望在我们对所需空间的假设错误时收到警报,而不是仅仅让数据被截断,我们希望测试函数的返回值并处理它指示的任何错误。我们还想检查一般错误代码,就像通常我们应该为每个可以发出错误信号的函数调用所做的那样:
if (result >= PIN_BUFFER_SIZE) {
fprintf(stderr, "PIN truncated\n");
exit(EXIT_FAILURE); // or handle it some less-drastic way
} else if (result < 0) {
// should not happen, but we're being thorough
fprintf(stderr, "Internal I/O error\n");
exit(EXIT_FAILURE); // or handle it some less-drastic way
}