2012-08-29 78 views
3

我正在將多個報告從HID設備讀取到unsigned char,然後嘗試將數據複製到std::vector。我還將數據寫入文件進行十六進制分析,當我查看它時,其內容似乎是正確的。但是,當我將其轉儲到控制檯時,std::vector似乎不包含正確的數據。如何將多個char讀取結合到一個std :: vector中?

這是代碼:

typedef vector<unsigned char> buffer_t; 

buffer_t sendCommand (hid_device *devh, const unsigned char cmd[], int reports) { 
    unsigned char outbuf[0x40]; 
    buffer_t retbuf(0x40 * reports); 

    hid_write(devh, cmd, 0x41); 

    int i; 
    FILE *file = fopen("test.out", "w+b"); 
    while (i++ < reports) { 
     hid_read(devh, outbuf, 0x40); 
     fwrite(outbuf, 1, sizeof(outbuf), file); 
     retbuf.push_back(*outbuf); 
    } 
    fclose(file); 
    cout << &retbuf[0]; 
    return retbuf; 
} 

我有一種感覺,我的方式在這裏下車的標誌;我對C/C++相當陌生,而且我一直堅持這一段時間。任何人都可以告訴我我做錯了什麼,或者指出我的方向更好嗎?

+0

您的載體將含有outbuf中只有第一個字符,因爲你正在使用* outbuf中。 – Shubhansh

回答

6

你想添加多個unsigned char對象到您的載體,但push_back只增加了一個。

因此,替換爲retbuf.push_back(*outbuf);之一:

for (size_t i = 0; i < sizeof(outbuf); ++i) { 
    retbuf.push_back(outbuf[i]); 
} 

std::copy(outbuf, outbuf+sizeof(outbuf), std::back_inserter(retbuf)); 

retbuf.insert(retbuf.end(), outbuf, outbuf+sizeof(outbuf)); 

,所有做同樣的事情。

你有一定規模的創建載體:

buffer_t retbuf(0x40 * reports); 

push_back在其結尾添加元素增加了向量的大小。您應該創建它清空:

buffer_t retbuf; 

或者,你可以安排載體有足夠的空間分配,準備好你要添加的元素:

retbuf.reserve(0x40 * reports); 

這是一個純粹的性能問題,但有時對於大型矢量或類型矢量(與unsigned char不同)在矢量用完內部空間並需要分配更多內容時複製/移動的成本較高時,這是一個重要問題。

關於樣式的說明:您重複幾次文字值0x40,並且還使用sizeof(outbuf)。它往往是最好的定義常量,並使用全名:

const int report_size = 0x40; 

這部分的情況下,在未來數變化,也這是關於你的代碼的可讀性 - 如果有人看到0x40它們可以或可能不會立即明白爲什麼這是正確的價值。如果有人看到report_size,那麼他們不知道真正的價值,直到他們查看它,但他們知道你爲什麼使用該值。

+0

感謝您的詳細解答。我已經嘗試了你的每一個解決方案,你說得對,他們都做同樣的事情。但是,當我使用'cout <<&rebuf [0]'(sizeof()'爲8,而不是0x40 *報告)時,輸出到控制檯仍然不正確。這可能與HID報告的結構有關嗎?他們寫的文件就好了... –

+0

原諒我的無知,這就是我所看到的。我認爲它會傾倒整個事情,但我現在明白爲什麼它不會......我將如何傾倒整個事情?我打算在一個結構體上覆制內存,以便我可以從報告中獲取所需的部分。 –

+0

'&retbuf [0]'是指向矢量中第一個'unsigned char'的指針。它具有'unsigned char *'類型,並且當'cout <<'時,地址被打印出來。對不起我以前的評論,我刪除了 - 這是錯誤的,因爲我錯過了&&。轉儲整個向量做任'的std ::拷貝(retval.begin(),retval.end(),ostream_iterator <無符號字符>(COUT));'否則'的std ::拷貝(retval.begin(), retval.end(),ostream_iterator (COUT,「「));',根據數據是否是人類可讀(以便打印它作爲字符)或二進制(以便將其打印爲數字)。 –

0

您的向量的類型爲unsigned char,這意味着它的每個元素都屬於這種類型。您的outbuf是無符號字符的數組

push_back()僅追加一個項目到所述載體的末端,所以push_back(*outbuf)將僅在outbuf的第一個元素添加到該載體中,不是所有的人。

要將所有數據放入矢量中,您需要逐一使用push_back或使用std::copy

1

問題出現在這一行:buffer_t retbuf(0x40 * reports);這意味着你創建了帶有無符號字符(零)缺省值的0x40 * reports元素的向量。然後push_back()只是向向量的末尾添加新元素,並不影響現有元素。

你需要這樣重寫:

buffer_t retbuf;     // Empty vector 
retbuf.reserve(0x40 * reports); // Preallocate memory for known element count 

這樣預期push_back()將工作從開始元素添加到空載體。

當然,你應該push_back()所有元素outbuf,不僅是第一個(*outbuf)。

0

注意,由於是outbuf中字符數組,然後* outbuf中將會因爲陣列/指針二重性的字符數組的第一個元素。

我想你也許想做的事:

typedef vector<string> buffer_t; // alternatively vector<unsigned char*> 
... 
retbuf.push_back(outbuf); 
... 

或者

typedef vector<unsigned char> buffer_t; 
... 
for (size_t i = 0; i < sizeof(outbuf); i++) 
    retbuf.push_back(outbuf); 
... 
1

推回多個值使用std :: vector的功能分配。例如:

std::vector<char>vec1; 
char array[3] = {'a', 'b', 'c'}; 
vec1.assign(array, array+3); 

我目前正在一個項目上工作,我不得不這樣做。

相關問題