2014-09-02 98 views
0

編寫兩個函數 - 一個將ascii轉換爲十六進制,然後反之。遇到非常奇怪的事情...用printf();聲明在Asc2Hex函數中註釋掉,它不起作用。如果我取消註釋,它可以工作......任何想法?如果有人知道更好的方式來做這種轉換,請讓我知道。將ASCII轉換爲十六進制,反之亦然 - 奇怪問題

#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; 
} 

回答

1

你有undefined behavior,因爲你返回一個指向局部變量的指針。當函數Asc2Hex返回時,變量buffer超出範圍,並且返回的指針無效。

最安全的解決方案是有兩個額外的參數,函數,緩衝區和它的大小(所以你不寫超出邊界)。另一個安全但不是很好的解決方案是使buffer變爲static變量,那麼它的生命週期就是整個程序,並且可以安全地返回指向它的指針。

0

返回一個指向局部變量的指針是個壞消息,並導致未定義的行爲。

編者按:sizeof(char)1

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()內存一個字節 - 告訴我在哪裏,實際上是相當重要的電腦!)

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); 
} 
+0

doh!我不知道我是如何錯過...謝謝大家的意見。 – 2014-09-02 23:09:05

相關問題