2015-06-17 2 views
-1

У меня есть std::stringstream с 1 байт:Как написать int в строковый поток?

std::stringstream message; 
message.write((const char[]) {0x55}, 1); 
std::string res(message.str()); 

Как Append int a = 1; (4 байта)?

Я хочу, чтобы получить в качестве значений, хранящихся в message-х, лежащих в основе std::string:

0x55 0x00 0x00 0x00 0x01 

И правильный инструмент я выбрал для работы с последовательностью байтов?

+0

Почему вы хотите получить '0x55 0x00 0x00 0x00 0x01'? Вы уверены, что хотите рассматривать его как буфер байта вместо текстовой строки? Просто прошу убедиться, что –

+0

Это может быть полезно (я не помечен как дубликат, потому что я честно не уверен): http://stackoverflow.com/questions/191757/c-concatenate-string-and-int –

+0

'std :: string' не является' std :: stringstream', выяснить, как использовать 'std :: stringstream', легко, и ваш синтаксис составлен. Какую книгу вы используете? –

ответ

2

«Как добавить int a = 1; (4 байта)?»

Просто так:

uint32_t a = 1; // Use uint32_t to be sure to have 4 bytes. 
message.write((const char*)&a, sizeof(a)); 

Как вы упоминаете «специальный протокол сокета», вам, вероятно, нужно позаботиться о сетевом порядке байтов с использованием функции htonl():

uint32_t a = htonl(1); 
+0

@Praetorian Я не работал над этим вопросом. –

+1

Это работает, спасибо!) – comm1x

0

Следующий сделаю, с функцией Append4ByteInteger делает фактическую работу:

#include <iostream> 
#include <sstream> 
#include <string> 

static std::stringstream& Append4ByteInteger (std::stringstream& stream, int value) { 
    auto v = static_cast<uint32_t>(value); 

    stream << static_cast<unsigned char>(v >> 24); 
    stream << static_cast<unsigned char>(v >> 16); 
    stream << static_cast<unsigned char>(v >> 8); 
    stream << static_cast<unsigned char>(v); 

    return stream; 
} 

int main() { 
    std::stringstream message; 
    message.write((const char[]) {0x55}, 1); 

    Append4ByteInteger(message, 1); 
    std::cout << "result: '" << message.str() << "'" << std::endl; 
} 

Вы можете проверить, что поток на самом деле содержит 0x00 0x00 0x00 0x01 с помощью утилиты шестнадцатеричного (например, hexdump).

Обратите внимание, что функция предполагает, что целое число имеет значение 0 или больше. Если вы хотите убедиться, что вы можете использовать вместо него unsigned int или, возможно, даже uint32_t, так как размер int зависит от платформы.

+0

Вы забыли сдвиг вправо перед вставкой в ​​поток. – Praetorian

+0

Абсолютно. Спасибо, я исправлю свой ответ! – stj

0

Письмо int может отличаться в зависимости от внутреннего байтового заказа, большого эндианта, мало-постороннего текста или других.

Было бы более портативным, чтобы замаскировать каждые байты логически, а затем поместить каждый символ без знака в поток

Вам нужно будет восстановить int на стороне ПОЛУЧАТЬ, снова используя логические операции, такие как сдвиг

Также, вероятно, вам не понадобятся все 4 байта, поэтому вы можете просто просто отправить 3, например.

Вы должны искать смещение и маскировку и понимать их, если вы планируете делать двоичные потоки.

Смежные вопросы