2012-06-07 3 views
1

У меня есть некоторые данные, которые должны соответствовать определенному протоколу пакетов. Я получаю указанные данные как std :: string.cramming/embeding integers в строки в C++

Мне нужно взять некоторые целочисленные значения и поместить их в строку в определенных местах. я не хочу преобразовать целое число в строковые значения; Я хочу скопировать фактические значения байтов в.

так, например, если моя строка «abcdefg», и у меня есть 2-байтовый короткий со значением 25, который я хочу положить в 1-ю позицию, «Не хочу» a25defg ». Я хочу «a» + 0x00 + 0x19 + «defg» (простите меня за это. Это был лучший способ, который я мог бы представить, чтобы проиллюстрировать, что я хочу).

есть ли способ сделать это, используя обычные строки C++? для меня это не возможность для повышения производительности благодаря системному req.

Из того, что я вижу, строка может помочь, но все примеры, которые я вижу, преобразуют число/short/integer в его версию ascii, и это не то, что я хочу.

Я могу легко сделать это с помощью массивов char, но мне было интересно, могу ли я сделать это со строками.

спасибо.

+1

Есть много вещей, которые влияют на вопрос. Первый из них заключается в том, использует ли протокол 'std :: string', потому что это текстовый протокол, или' std :: string' является злоупотреблением 'std :: vector ', будет обрабатывать протокол NUL символов в строке? Является ли размер строки фиксированной в протоколе? –

+0

да, давайте предположим, что. endianness проверяется до того, как этот код попадет в цель. – jasonmclose

+1

хорошие вопросы. строка является фиксированным размером, поскольку протокол определен. и да, протокол действительно нуждается в нулевых символах и может обрабатывать их, что является одной из причин использования std :: string. Я знаю, как это сделать, используя массивы char. Мне просто интересно, как это можно сделать с помощью std :: string. – jasonmclose

ответ

2

Вы говорите это легко сделать с массивами char, но это так же просто с std :: strings!

std::string str = "abcdef"; 
short val = 25; 
str[1] = val>>8; 
str[2] = val&255; 

Это работает так, как вы хотите. Если протокол имеет большое значение.

Edit:
Это работает только если вы хотите, чтобы заменить существующие символы в строке. Чтобы создать новую строку с нуля или добавить значение в конце, см. Ответ Дани.

+0

вот что я искал. мне действительно нужно немного узнать своих побитовых операторов. теперь позвольте мне задать вам второй вопрос. как я могу добавить короткое слово таким же образом? мне нужно добавить 2 значения, а затем использовать один и тот же метод, или есть лучший способ? спасибо много кстати. – jasonmclose

+0

Ну, вы не должны использовать индексирование [] для добавления символов (т. Е. Писать после текущего конца строки), чтобы вы могли, например, добавить «xx» «сначала, а затем изменить содержимое добавленных байтов. Но тогда это становится менее простым и изящным методом ... –

+0

@MrLister: да, я еще не видел этого. : / –

2

Его не рекомендуется, но вы можете просто переосмысливать его:

short something = 25; 
string something_string(reinterpret_cast<unsigned char*>(&something), 
         sizeof(something)); 
// something_string == 19 00 

Вы должны заботиться о порядок байтов, хотя (как hton)

+0

и 'str.append (reinterpret_cast (val), sizeof (val));', а также 'str.замените (1, 2, reinterpret_cast (val), sizeof (val)); 'чтобы сэкономить вам небольшое количество времени. –

0
template<size_t N> 
void cram_helper(unsigned long long value, char* const dst) 
{ 
    char* p = dst + N; 
    while (p > dst) { *--p = value & 0xFF; value >>= 8; } 
} 

template<typename T> 
void cram(T t, char* dst) 
{ 
    cram_helper<sizeof(T)>(t, dst); 
} 

char buffer[] = { "abcdefg" }; 
short s = 25; 
cram(s, buffer+1); 

string buffer1 = "abcdefg"; 
cram(s, &buffer[1]); 

template<size_t N, typename Container> 
void cram_helper(unsigned long long value, Container& dst, int initial_index) 
{ 
    char index = initial_index + N; 
    while (index > initial_index) { dst[--index] = value & 0xFF; value >>= 8; } 
} 

template<typename T, typename Container> 
void cram(T t, Container& dst, size_t initial_index = 0) 
{ 
    cram_helper<sizeof(T)>(t, dst, initial_index); 
} 

std::string buffer2 = "abcdefg"; 
short s = 25; 
cram(s, buffer2, 1); 
+0

можно ли это сделать без использования char * или char массивов? используя прямой доступ к std :: string или std :: string library? – jasonmclose

+0

@jason: Просто добавил это. –

+0

Большое вам спасибо. – jasonmclose