Объединение std :: string и std :: vector <char> - PullRequest
1 голос
/ 30 декабря 2010

Это не настоящий код, но это представляет мою проблему.

std::string str1 = "head";
char *buffer = "body\0body"; // Original code has nullbytes;
std::string str2 = "foot";
std::vector<char> mainStr(buffer, buffer + strlen(buffer));

Я хочу поставить str1 и str2 на mainStr в порядке:

headbody \ 0bodyfoot

Таким образом, двоичные данные сохраняются. Возможно ли это сделать?

PS : Спасибо за сообщение, что часть strlen неверна. Я просто использовал его для представления длины buffer. :)

Ответы [ 7 ]

3 голосов
/ 30 декабря 2010

Должен быть какой-то способ определения длины данных в «буфере». Обычно для этого используется символ 0, и большинство стандартных текстовых функций предполагают это. Поэтому, если вы используете символ 0 для других целей, вы должны предоставить другой способ узнать длину данных.

Просто например:

char buffer[]="body\0body";
std::vector<char> mainStr(buffer,buffer+sizeof(buffer)/sizeof(buffer[0]));

Здесь мы используем массив, потому что он предоставляет больше информации, чем указатель - размер хранимых данных.

2 голосов
/ 30 декабря 2010

Вы не можете использовать strlen, так как он использует '\ 0' для определения конца строки.Тем не менее, следующее будет делать то, что вы ищете:

std::string head = "header";
std::string foot = "footer";
const char body[] = "body\0body";

std::vector<char> v;
v.assign(head.begin(), head.end());
std::copy(body, body + sizeof(body)/sizeof(body[0]) - 1, std::back_inserter<std::vector<char> >(v));
std::copy(foot.begin(), foot.end(), std::back_inserter<std::vector<char> >(v));

Поскольку буфер символов добавляет символ NUL в конце строки, вы захотите проигнорировать его (следовательно, -1 изпоследний итератор).

1 голос
/ 30 декабря 2010

Вы можете использовать IO-потоки.

std::string str1 = "head";
const char *buffer = "body\0body"; // Original code has nullbytes;
std::string str2 = "foot";
std::stringstream ss;
ss.write(str1.c_str(), str1.length())
  .write(buffer, 9) // insert real length here
  .write(str2.c_str(), str2.length());
std::string result = ss.str();

std::vector<char> vec(result.c_str(), result.c_str() + result.length());
1 голос
/ 30 декабря 2010

кстати.strlen не будет работать, если в вашей строке есть нулевые байты!

Код для вставки в вектор:

front:

mainStr.insert(mainStr.begin(), str1.begin(), str1.end());

back:

mainStr.insert(mainStr.end(), str2.begin(), str2.end());

С вашим кодом выше (при использовании strlen будет напечатано)

headbodyfoot

EDIT: просто изменили copy на insert, поскольку copy требуетпространство, которое будет доступно, я думаю.

1 голос
/ 30 декабря 2010

Вы можете использовать std::vector<char>::insert, чтобы добавить нужные данные в mainStr.

Примерно так:

std::string str1 = "head";
char buffer[] = "body\0body"; // Original code has nullbytes;
std::string str2 = "foot";

std::vector<char> mainStr(str1.begin(), str1.end());
mainStr.insert(mainStr.end(), buffer, buffer + sizeof(buffer)/sizeof(buffer[0]));
mainStr.insert(mainStr.end(), str2.begin(), str2.end());

Отказ от ответственности: Я не скомпилировал его.

0 голосов
/ 30 декабря 2010
 mainStr.resize(str1.length() + str2.length() + strlen(buffer));  
 memcpy(&mainStr[0], &str1[0], str1.length());  
 memcpy(&mainStr[str1.length()], buffer, strlen(buffer));  
 memcpy(&mainStr[str1.length()+strlen(buffer)], &str2[0], str2.length());
0 голосов
/ 30 декабря 2010

str1 и str2 являются строковыми объектами, которые пишут текст.

Мне бы хотелось, чтобы компиляторы потерпели неудачу в таких операторах, как объявление буфера, и мне все равно, какой старый код он нарушает.Если вы все еще строите его, вы все равно можете исправить его и вставить const.

Вам нужно изменить объявление вектора, потому что strlen остановится на первом нулевом символе.Если бы вы сделали

char buffer[] = "body\0body";

, то sizeof (буфер) фактически дал бы вам то, что вы хотите, хотя вы также получите конечный нулевой терминатор.

Как только ваш вектор mainStrустановить правильно, вы могли бы сделать:

std::string strConcat;
strConcat.reserve( str1.size() + str2.size() + mainStr.size() );
strConcat.assign(str1);
strConcat.append(mainStr.begin(), mainStr.end());
strConcat.append(str2);

, если вектор был установлен с использованием буфера, buffer + sizeof (buffer) -1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...