Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将ASCII转换为十六进制,反之亦然-奇怪的问题_C_Printf_Hex_Ascii - Fatal编程技术网

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

将ASCII转换为十六进制,反之亦然-奇怪的问题,c,printf,hex,ascii,C,Printf,Hex,Ascii,正在编写两个函数,一个是将ascii转换为十六进制,另一个是将ascii转换为十六进制。遇到了非常非常奇怪的事情。。。使用printf();语句在Asc2Hex函数中被注释掉,它不起作用。如果我取消注释它,它会工作。。。有什么想法吗?如果有人知道更好的转换方法,请告诉我 #include <stdio.h> #include <string.h> char *Asc2Hex(char *); int main() { char *test = Asc2Hex

正在编写两个函数,一个是将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;
}
#包括
#包括
char*Asc2Hex(char*);
int main()
{
字符*测试=Asc2Hex(“ABCDEFG”);
printf(“测试:%s\n”,测试);
}
char*Asc2Hex(char*data){
int i,len=strlen(数据);
字符缓冲区[len+1];
char*pbuffer=缓冲区;
//printf(“字符串:%s\n”,数据);
对于(i=0;i<(len*sizeof(char));i++){
sprintf(pbuffer+i*2、%x、*(data+i));
}
返回pbuffer;
}
因为返回一个指向局部变量的指针,所以您有。当函数
Asc2Hex
返回时,变量
buffer
超出范围,返回的指针无效


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

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


编辑说明:
sizeof(char)
1

正如已经确定的那样,在定义局部变量的函数返回后,您的代码尝试使用指向该局部变量的指针,这是未定义的行为,根据C标准,任何结果都是有效的,包括“硬盘上的所有文件都被擦除”。避免未定义的行为

“更好”的方法包括将输出缓冲区传递给转换函数,确保每个输入字符打印2个十六进制数字,如果plain
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;
}
#包括
#包括
char*Asc2Hex(常量char*数据,char*缓冲区);
内部主(空)
{
字符缓冲区[2*sizeof(“ABCDEFG”)];
char*test=Asc2Hex(“ABCDEFG”,缓冲区);
printf(“测试:%s\n”,测试);
返回0;
}
字符*Asc2Hex(常量字符*数据,字符*缓冲区)
{
int len=strlen(数据);
对于(int i=0;i
这并不理想;它不能证明字符串过长和缓冲区过小。要解决这个问题,您需要将缓冲区长度传递到函数中,并确保缓冲区没有溢出。修改后的代码并不需要返回传入的指针,但如果传入缓冲区长度,则需要某种方法返回成功/失败


(从技术上讲,它分配了
main()
缓冲区不需要的一个字节的内存-告诉我一台计算机的实际情况!)

解决分配问题后,您的代码可能会变成这样:

#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);
}
#包括
#包括
#包括
char*Asc2Hex(char*data){
int i,len=strlen(数据);
char*buffer=malloc(2*len+1);
if(缓冲区){
对于(i=0;i
doh!我不知道我是怎么错过的。。。谢谢大家的意见。