2016-09-30 46 views
1

我正在讀取無符號字符數組中的命令行十六進制參數。我的代碼:十六進制轉換在CPP中出現嚴重錯誤

#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 
#include <memory.h> 
#include <cstring> 

unsigned char key[16] ={0x00, 0x00, 0x00, 0x00, 
           0x00, 0x00, 0x00, 0x00, 
           0x00, 0x00, 0x00, 0x00, 
           0x00, 0x00, 0x00, 0x00}; 


int main(int argc, char** argv){ 
     char hex_pref[]="0x"; 
     for (int i = 0; i < 16; i++){ 
       key[i] = strtol(strcat(hex_pref, argv[i]), NULL, 16); 
       std::cout << argv[i] << "\t"; 
     } 
     std::cout << std::endl; 
     for (int i = 0; i < 16; i++) 
       std::cout << key[i] << "\t"; 
     std::cout << std::endl; 
     return 0; 
} 

該程序的輸出是非常不可預測的。每次我改變參數,我都會得到奇怪的結果。

我運行它像

./a.out ab 32 bf 00 0a 2e 4c 3d 25 db 66 22 84 fb 19 72 

我試圖調試,但沒有答案。有什麼建議麼?謝謝。


做到了這一點,但問題仍然存在,因爲我無法驗證密鑰[我]有。

char hex_pref[4]; 
     strcpy(hex_pref, "0x"); 
     for (int i = 0; i < 16; i++){ 
       strcat(hex_pref, argv[i]); 
       key[i] = strtol(hex_pref, NULL, 16); 
       //std::cout << argv[i] << "\t"; 
     } 
     std::cout << std::endl; 
     for (int i = 0; i < 16; i++) 
       std::cout << std::hex << key[i] << "\t"; 
     std::cout << std::endl; 
     return 0; 

多了一個失敗的嘗試。現在作爲一個用戶說,密鑰[I]打印無用即使標準::六角

for (int i = 1; i < 17; i++){ 
       //strcat(hex_pref, argv[i]); 
       key[i-1] = strtol(argv[i], NULL, 16); 
       //std::cout << argv[i] << "\t"; 
     } 
     std::cout << std::endl; 
     for (int i = 0; i < 16; i++) 
       std::cout << std::hex << key[i] << "\t"; 
     std::cout << std::endl; 
     return 0; 
+0

你可以更好的使用sscanf函數用於此目的 –

+0

是什麼,輸出什麼樣子的? –

+0

這與[tag:cmd]有什麼關係? – aschipfl

回答

2

問題1:

argv[0]是不提供的參數的第一用戶。 arg[0]保留供實施使用。通常它是用於執行程序的命令。在這種情況下「./a.out」。 「./a.out」不會轉換爲導致不良行爲的整數,因爲strtol未被檢查有效性。

解決方案:從argv[1]開始,並相應地增加for循環。

附錄:不要忽略strtol的第二個參數。在無效輸入中選擇 非常方便。用戶可以輸入「fubar」,你會錯過它。

問題2:

覆蓋部分由羅賓·約翰遜的回答。 hex_pref不足以容納「0x」和輸入用戶參數。幸運的是沒有必要。 strtol的第三個參數指定輸入是十六進制的。

解決方案:刪除strcathex_pref

問題3:

您正在輸出無符號字符。這些將被<<解釋爲您輸入的任何數字的ASCII值。這會給您帶來令人討厭的廢話字符輸出,嗶嗶聲以及其他任何由該數字表示的內容,而不是很好的乾淨的十六進制值。

解決方案:unsigned int key或鑄造key[i]unsigned int打印時。

半問題4:

您不輸出十六進制結果。

解決方案:使用std::hex

+0

std :: hex仍然會導致垃圾值。我無法將密鑰更改爲無符號整型,因爲這是更大程序的一部分。 – algoProg

+0

@algoProg使用該案例的解決方案進行編輯:打印時將'key [i]'強制轉換爲'unsigned int'。 – user4581301

+0

還有任何想法爲什麼std :: hex不會工作? – algoProg

1

的strcat()正嘗試結果放入其沒有準備,因爲它具有大小爲「2」 hex_pref 。這永遠不會正常工作。

http://www.cplusplus.com/reference/cstring/strcat/

與你原來的做法是一致的。下面的代碼是「正確的」。併產生良好的輸出(見下面的代碼)。

#include <stdio.h> 
#include <iostream> 
#include <stdlib.h> 
#include <memory.h> 
#include <cstring> 

unsigned char key[16] = { 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00 }; 


int main(int argc, char** argv) 
    { 
    char hex_pref[] = "0x"; 
    for (int i = 1; i < 17 && i < argc; ++i) 
     { 
     std::cout << argv[i] << "\t"; 
     if (strlen(argv[i]) < 3) 
      { 
      char result[5]; 
      result[0]= 0; 
      strcat(result, hex_pref); 
      strcat(result, argv[i]); 
      key[i-1] = char(strtol(result, NULL, 16)); 
      } 
     } 
    std::cout << std::endl; 
    for (int i = 0; i < 16; ++i) 
     { 
     std::cout << int(key[i]) << "\t"; 
     } 
    std::cout << std::endl; 
    return 0; 
    } 

輸出是:

C:\Users\rjohnson\Desktop\Workspaces\TestHex\Debug>testhex ab 32 bf 00 0a 2e 4c 3d 25 db 66 22 84 fb 19 72 
ab  32  bf  00  0a  2e  4c  3d  25  db  66  22  84  fb  19  72 
171  50  191  0  10  46  76  61  37  219  102  34  132  251  25  114 

一種不同的方法使用流和字符串將是 「真正」 的方式。這裏沒有真正的空間來提供完整的解釋,但有很多教程和全面的例子。

string result; 
result += "0x"; 
result += argv[i]; 
key[i]= strtol(result.c_str(), NULL, 16); 
+0

我現在明白了。但是,「0x」+ argv [i]怎麼樣? – algoProg

+0

讓我編輯答案。 –

+0

切換到'string'的良好通話。推薦進一步,用['std :: stol'](http://en.cppreference.com/w/cpp/string/basic_string/stol)替換'strtol'。對無效的用戶輸入提供了一個很好的例外。 – user4581301

-1

您的代碼可能工作的一種可能的版本如下。 無論如何,我會考慮考慮更好的設計。 很可能,下面的代碼也可能會出現很多可能的問題。

unsigned long long key[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 


int main(int argc, char** argv) { 



for (int i = 1; i < argc; i++) { 

    sscanf(argv[i], "%x", &(key[i])); 

    std::cout << argv[i] << "\t"; 
} 
std::cout << std::endl << std::endl; 
for (int i = 0; i < argc; i++) 
    std::cout << key[i] << "\t"; 
std::cout << std::endl; 

getchar(); 
return 0; 

}

+0

不是。這仍然錯過了一半的錯誤。 – user4581301

+0

我很確定這段代碼還有很多可能的問題,但它可能會提供一個初始工作版本。 –

相關問題