簡體   English   中英

在C ++中將無符號long轉換為char *的最佳方法是什么

[英]What is the best way to convert an unsigned long to char* in C++

我需要通過套接字發送一些unsigned long 由於unsigned long為4字節,因此接收方僅期望4字節。 我編寫的轉換函數可以在下面找到,但僅當必須存儲在char中的數字不大於127時才可以。 0x7F。 對於大於0x7f的值,我希望擴展的ASCII表( http://www.asciitable.com/ )中的字符將存儲在char中,但是絕對不是這種情況。 例如,對於0x90,不存儲任何內容。 我正在將VS12與Unicode字符集一起使用。

有什么想法可以使轉換正確嗎?

void number2char(unsigned long number, char* nrAsByte){
    std::stringstream numberSS;
    numberSS << std::hex << number;
    int length = numberSS.str().length();
    length = length / 2.0 + 0.5;
    nrAsByte = new char[sizeof(number)]();
    std::fill(nrAsByte, nrAsByte + length, '\x20');
    while (length > 0){
        int lastTwo = (number & 0xff);
        number >>= 8;
        unsigned char a = lastTwo;  // this doesn't work if lastTwo > 0x7F
        std::memcpy(nrAsByte + length - 1, &a, 1);
        --length;
    }
}

我為代碼感到抱歉,它沒有經過我的良好測試,並且包含錯​​誤,請不要使用它,而是遵循答案中的建議

為什么不這樣:

void number2char(unsigned long number, char* nrAsByte){
   unsigned char *dst= reinterpret_cast<unsigned char *> nrAsByte;
   for (int i=0; i<sizeof(unsigned long); ++i) {
      *dst++= number & 0xFF;
      number >>= 8;
   }
}

嗯,我一直在玩弄安東尼奧的答案,因為它感覺並不完整和正確,最后我得到的結果比我預期的還要復雜,但是有時它的目的是復雜性。

下面的代碼還手動完成了htonl / ntohl的轉換(可能是相反的字節序,因此不希望將其與htonl混合使用,要么使用它,要么用htonl重寫它)。

與Antonio的來源不同,當輸入數字類型為8字節長時(在我的測試平台unsigned long為8字節-BTW,嘗試嗎?!),它不會覆蓋內存,它將截斷該值以適合所需的網絡字符*緩沖。

我試圖對其進行廣泛評論,以使您在每個決定中增加進一步的復雜性(在基本上使用unsigned int number用作(char *)(&number) ,該想法也可以提供,但不能保護字節序,並且可能會終止如果您混合使用不同的長度類型,則在覆蓋內存中)。 但是,如果您看到不清楚的地方,請問任何事情。

#include <iostream>
#include <string>

// Experiment with different types to see differences
// (and how data are truncated when sizeof number > sizeof networkdata)

//typedef unsigned int numberType_t;
typedef unsigned long numberType_t;  // on my platform this is 8 bytes long

constexpr int networkBytesSize = 4;  // number of chars to be sent trough network with (char *)
// define network data type:
// used "struct" to make sizeof(networkData_t) return actual number of bytes
typedef struct {
    unsigned char d[networkBytesSize];
    char *cptr() { return reinterpret_cast<char *>(d); }
} networkData_t;

// Writes number into network char* buffer nrAsByte, endianness agnostic
void number2char(numberType_t number, networkData_t & nrAsByte) {
    for (size_t i = 0; i < sizeof(networkData_t); ++i) {
        nrAsByte.d[i] = number & 0xFF;
        number >>= 8;
    }
}

// Read number back from network char* buffer
numberType_t char2number(const networkData_t & nrAsByte) {
    numberType_t number = 0;
    size_t i = sizeof(networkData_t);
    while (i--) number = (number<<8) | nrAsByte.d[i];
    return number;
}

int main()
{
    printf("numberType_t size in bytes: %lu, networkData_t size in bytes: %lu\nAll following numbers are hex:\n",
            sizeof(numberType_t), sizeof(networkData_t));

    numberType_t number = numberType_t(0x9ABCDEF0123456FEul);
    std::cout << "source number: " << std::hex << number << std::endl;

    // Write number into char buffer
    networkData_t networkData;
    number2char(number, networkData);
    std::cout << "network bytes:";
    for (size_t i = 0; i < sizeof(networkData_t); ++i) std::cout << " [" << unsigned(networkData.d[i]) << "]";
    std::cout << std::endl;

    // Test usability of (char *) pointer access
    const char * testCharPtrConversion = networkData.cptr();
    printf("as char * (decimal signed): %d %d ...\n", testCharPtrConversion[0], testCharPtrConversion[1]);

    // Read number from char buffer
    number = char2number(networkData);
    std::cout << "read number: 0x" << std::hex << number << std::endl;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM