编写两个函数 - 一个将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;
}
答案 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;
}
这不理想;它不能证明超长字符串和小尺寸缓冲区。要解决这个问题,您需要将缓冲区长度传递给函数,并确保缓冲区没有溢出。修改后的代码并不真正需要返回传入的指针,但如果传入缓冲区长度,则需要一些方法来返回成功/失败。
(从技术上讲,它分配了buffer
中main()
不需要的一个字节的内存 - 告诉我一台计算机真正重要的地方!)