简体   繁体   中英

Wrong output when converting string to IP address

I'm trying to convert a string to IP address. The input string is an unsigned integer converted to std::string , for example "123456" . The code below is not correct, as it produces unreadable binary characters.

std::string str2IP(const std::string& address)
{
    uint32_t ip = std::strtoul(address.c_str(), NULL, 0);
    unsigned char bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;

    std::stringstream ss;
    ss << bytes[3] << "." << bytes[2] << "." << bytes[1] << "." << bytes[0];
    return ss.str();
}

The formatted output functions (operator << ) of I/O streams treat char , signed char , and unsigned char as characters —they interpret the value as a character code, not as a number. This code will output A :

unsigned char c = 65;
std::cout << c;

The same holds for std::uint8_t on most implementations, because they just use it as a typedef to an unsigned char . You need to use a proper numerical type, such as unsigned short :

std::string str2IP(const std::string& address)
{
    uint32_t ip = std::strtoul(address.c_str(), NULL, 0);
    unsigned short bytes[4];
    bytes[0] = ip & 0xFF;
    bytes[1] = (ip >> 8) & 0xFF;
    bytes[2] = (ip >> 16) & 0xFF;
    bytes[3] = (ip >> 24) & 0xFF;

    std::stringstream ss;
    ss << bytes[3] << "." << bytes[2] << "." << bytes[1] << "." << bytes[0];
    return ss.str();
}

Outputting char s to a std::stringstream has the semantics of outputting the encoded character represented by that char rather than a numerical representation.

You can force numerical representation by using unary plus to promote those char s:

ss << +bytes[3] << "." << +bytes[2] << "." << +bytes[1] << "." << +bytes[0];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM