将ASCII转换为十六进制,反之亦然 - 奇怪的问题

时间:2014-09-02 18:25:44

标签: c printf hex ascii

编写两个函数 - 一个将ascii转换为十六进制,然后反之亦然。遇到一些非常奇怪的东西......用printf();语句在Asc2Hex函数中注释掉,它不起作用。如果我取消注释,它可以工作......任何想法?如果有人知道更好的转换方法,请告诉我。

#include <stdio.h>
#include <string.h>

char *Asc2Hex(char *);

int main()
{

    char *test = Asc2Hex("ABCDEFG");
    printf("Test: %s\n",test);

}


char *Asc2Hex(char *data){
    int i, len = strlen(data);
    char buffer[len+1];
    char *pbuffer = buffer;
    //printf("String: %s\n",data);
    for(i = 0; i < (len * sizeof(char)); i++){
        sprintf(pbuffer+i*2, "%x",*(data+i));
    }
    return pbuffer;
}

4 个答案:

答案 0 :(得分:1)

你有undefined behavior,因为你返回一个指向局部变量的指针。当函数Asc2Hex返回时,变量buffer超出范围,并且返回的指针无效。

最安全的解决方案是为函数,缓冲区及其大小增加两个额外的参数(这样你就不会超出边界)。另一个安全但不太好的解决方案是使buffer成为static变量,然后它的生命周期就是整个程序,你可以安全地返回指向它的指针。

答案 1 :(得分:1)

修复分配问题,您的代码可能会变成这样:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *Asc2Hex(char *data) {
    int i, len = strlen(data);
    char *buffer = malloc(2*len+1);
    if (buffer) {
        for(i = 0; i < len; i++){
            sprintf(&buffer[i*2],"%.2x",data[i]&0xff);
        }
    }
    return buffer;
}

int main() {    
    char *test = Asc2Hex("\xff");
    printf("Test: %s\n",test);
    if (test) free(test);
}

答案 2 :(得分:0)

返回指向局部变量的指针是坏消息,并导致未定义的行为。

编辑说明:sizeof(char)1

答案 3 :(得分:0)

如前所述,您的代码在定义它的函数返回后尝试使用指向局部变量的指针,这是未定义的行为,并且根据C标准,任何结果都是有效的,包括'硬盘上的所有文件都被删除”。避免未定义的行为!

“更好”的方法包括将输出缓冲区传递给转换函数,确保每个输入字符打印2个十六进制数字,如果普通char是签名类型,则仍然可以预期结果:

#include <stdio.h>
#include <string.h>

char *Asc2Hex(const char *data, char *buffer);

int main(void)
{
    char  buffer[2*sizeof("ABCDEFG")];
    char *test = Asc2Hex("ABCDEFG", buffer);
    printf("Test: %s\n", test);
    return 0;
}

char *Asc2Hex(const char *data, char *buffer)
{
    int len = strlen(data);
    for (int i = 0; i < len; i++)
        sprintf(buffer+i*2, "%.2x", data[i] & 0xFF);
    return buffer;
}

这不理想;它不能证明超长字符串和小尺寸缓冲区。要解决这个问题,您需要将缓冲区长度传递给函数,并确保缓冲区没有溢出。修改后的代码并不真正需要返回传入的指针,但如果传入缓冲区长度,则需要一些方法来返回成功/失败。

(从技术上讲,它分配了buffermain()不需要的一个字节的内存 - 告诉我一台计算机真正重要的地方!)