我一直在努力创建一个程序,它接受一个地址并为每两个字符反转它。示例输入将是“0xefba5896”,理想情况下它的输出将是“\ x96 \ x58 \ xba \ xef”。我遇到的麻烦是前几个字节有效,但最后一个字节无法打印。我的代码如下:
int i;
char *add = argv[1];
char rev[8];
char xa[2];
strncpy(rev, &add[2], strlen(add));
for (i = strlen(rev) - 2; i > -2; i-=2) {
if (i == 0) {
strncpy(xa, &rev[0], 2);
} else {
strncpy(xa, &rev[i], 2);
xa[2] = '\0';
}
printf("\\x%s", xa);
}
如果我输入“0xefba5896”,我的输出是:
\x96\x58\xba\x
如果答案对某人显而易见,请原谅我。我一直在学习C只有一个星期。 任何帮助都会非常感激!
答案 0 :(得分:0)
如果strlen(add)
长于10,则将strncpy
作为限制因素传递给add
是没有意义的,
你仍会溢出rev
!
您必须传递目标的大小,而不是源的大小。所以正确的电话是
strncpy(rev, add+2, sizeof rev);
rev[sizeof(rev) - 1] = 0;
另请注意,strncpy
不一定要写'\0'
- 终止字节
如果目的地不够长,那么你应该总是设置
'\0'
- 自己终止字节。
另请注意,xa[2] = '\0';
溢出xa
,因为xa
的大小为2,所以
最大索引是1
。如果您想在xa
中存储2个字符,那么
xa
必须至少为维度3. rev
也是如此。所以你必须声明xa
:
char rev[9];
char xa[3];
因此,当您使用strncpy
时,您应该像这样使用它:
char dest[8];
strncpy(dest, src, sizeof dest);
dest[sizeof(dest) - 1] = 0;
所以你可以像这样重写你的程序:
int main(int argc, char **argv)
{
if(argc != 2)
{
fprintf(stderr, "usage: %s address\n", argv[0]);
return 1;
}
size_t len;
char *add = argv[1];
char rev[9];
char xa[3];
strncpy(rev, add + 2, sizeof rev);
rev[sizeof(rev) - 1] = 0;
len = strlen(rev);
if(len & 1)
{
fprintf(stderr, "Invalid length of address, needs an even number of characters\n");
return 1;
}
for(size_t i = len - 2; i >= 0; i -= 2)
{
strncpy(xa, rev + i, sizeof xa);
xa[sizeof(xa) - 1] = 0;
printf("\\x%s", xa);
fflush(stdout);
}
putchar('\n');
return 0;
}