每两个字符反转输入

时间:2018-04-07 23:13:41

标签: c

我一直在努力创建一个程序,它接受一个地址并为每两个字符反转它。示例输入将是“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只有一个星期。 任何帮助都会非常感激!

1 个答案:

答案 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;
}