c中的字符串不需要的字符
String unwanted character in c
我正在尝试将整数添加到字符串中。当我调试我的代码时,一切正常,但是当我 运行 它通常会在字符串的开头打印两个不需要的字符。我该如何避免这种情况?
int number_of_ints = 5;
char s[number_of_ints*2];
char suffix[4];
for(int i = 1; i <= number_of_ints; i++){
snprintf(suffix, number_of_ints, "%d*", i);
strncat(s, suffix, 2);
printf("%s\n", s);
}
这是正常构建和运行编译代码时的输出。
`û1*
`û1*2*
`û1*2*3*
`û1*2*3*4*
`û1*2*3*4*5*
Strings 在 C 中是一个非零字节序列,后跟一个值为零的终止字节(空终止字节,'[=11=]'
)。
您必须调整缓冲区大小以拥有额外的 space,以保证为这个空终止字节留出空间。
您还必须确保缓冲区的内容包含有效的字符串。为此,您可以将缓冲区的第一个元素设置为空终止字节,从而创建一个零长度字符串。
无法初始化缓冲区的内容意味着它将包含 不确定的值,并将此类缓冲区传递给需要有效 string will invoke Undefined Behavior.[=20 的函数=]
snprintf
的第二个参数最多应该是目标缓冲区的大小。
最后,考虑在适用时使用 size_t
,因为它是处理内存大小的合适类型(例如,调整大小 variable-length arrays;sizeof
运算符解析为这种类型;snprintf
期望这种类型作为它的第二个参数)。
#include <stdio.h>
#include <string.h>
int main(void) {
size_t number_of_ints = 5;
char s[number_of_ints * 2 + 1];
char suffix[4];
s[0] = '[=10=]';
for (size_t i = 1; i <= number_of_ints; i++) {
snprintf(suffix, sizeof suffix, "%zu*", i);
strncat(s, suffix, 2);
printf("%s\n", s);
}
}
您的缓冲区初始化和大小存在一些问题。
- 您的缓冲区大小太短了 0 终止所需的 1 个字节。添加最后一个数字会导致缓冲区溢出和未定义的行为。
- 此外,计算出的大小只要
number_of_ints<10
就足够了,因为它只允许个位数。
- 那个缓冲区没有初始化,我们很可能没有保存空字符串。访问它(通过
strcat
等)会调用未定义的行为。
- 您提供给
snprintf
的大小与缓冲区的大小无关。
您应该应用这些更改:
#include <stdio.h>
#include <string.h>
int main(void)
{
int number_of_ints = 5;
char s[number_of_ints*2+1];
char suffix[4];
s[0] = 0;
for (int i = 1; i <= number_of_ints; i++)
{
snprintf(suffix, sizeof(suffix), "%d*", i);
strncat(s, suffix, 2);
printf("%s\n", s);
}
}
我正在尝试将整数添加到字符串中。当我调试我的代码时,一切正常,但是当我 运行 它通常会在字符串的开头打印两个不需要的字符。我该如何避免这种情况?
int number_of_ints = 5;
char s[number_of_ints*2];
char suffix[4];
for(int i = 1; i <= number_of_ints; i++){
snprintf(suffix, number_of_ints, "%d*", i);
strncat(s, suffix, 2);
printf("%s\n", s);
}
这是正常构建和运行编译代码时的输出。
`û1*
`û1*2*
`û1*2*3*
`û1*2*3*4*
`û1*2*3*4*5*
Strings 在 C 中是一个非零字节序列,后跟一个值为零的终止字节(空终止字节,'[=11=]'
)。
您必须调整缓冲区大小以拥有额外的 space,以保证为这个空终止字节留出空间。
您还必须确保缓冲区的内容包含有效的字符串。为此,您可以将缓冲区的第一个元素设置为空终止字节,从而创建一个零长度字符串。
无法初始化缓冲区的内容意味着它将包含 不确定的值,并将此类缓冲区传递给需要有效 string will invoke Undefined Behavior.[=20 的函数=]
snprintf
的第二个参数最多应该是目标缓冲区的大小。
最后,考虑在适用时使用 size_t
,因为它是处理内存大小的合适类型(例如,调整大小 variable-length arrays;sizeof
运算符解析为这种类型;snprintf
期望这种类型作为它的第二个参数)。
#include <stdio.h>
#include <string.h>
int main(void) {
size_t number_of_ints = 5;
char s[number_of_ints * 2 + 1];
char suffix[4];
s[0] = '[=10=]';
for (size_t i = 1; i <= number_of_ints; i++) {
snprintf(suffix, sizeof suffix, "%zu*", i);
strncat(s, suffix, 2);
printf("%s\n", s);
}
}
您的缓冲区初始化和大小存在一些问题。
- 您的缓冲区大小太短了 0 终止所需的 1 个字节。添加最后一个数字会导致缓冲区溢出和未定义的行为。
- 此外,计算出的大小只要
number_of_ints<10
就足够了,因为它只允许个位数。 - 那个缓冲区没有初始化,我们很可能没有保存空字符串。访问它(通过
strcat
等)会调用未定义的行为。 - 您提供给
snprintf
的大小与缓冲区的大小无关。
您应该应用这些更改:
#include <stdio.h>
#include <string.h>
int main(void)
{
int number_of_ints = 5;
char s[number_of_ints*2+1];
char suffix[4];
s[0] = 0;
for (int i = 1; i <= number_of_ints; i++)
{
snprintf(suffix, sizeof(suffix), "%d*", i);
strncat(s, suffix, 2);
printf("%s\n", s);
}
}