преобразование c ++ std :: vector <std :: string> в std :: vector <unsigned char> (и наоборот) - PullRequest
1 голос
/ 22 февраля 2012

Существует ли простой способ преобразования std::vector<std::string> в std::vector<unsigned char> (и обратно в std::vector<std::string>, без необходимости вручную преобразовывать каждую строку и добавлять разделитель, например запятую?

Ответы [ 4 ]

1 голос
/ 22 февраля 2012

Краткий ответ: нет.

Реализация векторов и строк осуществляется в виде независимых, распределенных в куче массивов.Следовательно, вы можете преобразовать vector<string> в char** (зубчатый массив массивов char) и vector<unsigned char> в char* (массив char), думая о внутренних объектах.Это превращает вашу проблему в: есть ли способ объединить массивы, не копируя их?

Нет.Нет, нет.

0 голосов
/ 22 февраля 2012

Первый вопрос: почему и что вы пытаетесь сделать? Что это std::vector<std::string> представляют, и какова должна быть семантика преобразование будет? Если вы просто хотите объединить, то самый простой решение будет что-то вроде:

std::vector<unsigned char> results;
for ( std::vector<std::string>::const_iterator iter = source.begin();
        iter != source.end();
        ++ iter ) {
    results.insert( results.end(), iter->begin(), iter->end() );
}

Неявное преобразование char в unsigned char позаботится о остаток.

Если вам нужно вставить какой-то разделитель или терминатор для каждого Строка в источнике, вы можете сделать это и в цикле: для терминатор, просто добавьте его (push_back) после insert; для разделитель, я обычно добавляю его условно перед insert, e.g.:

std::vector<unsigned char> results;
for ( std::vector<std::string>::const_iterator iter = source.begin();
        iter != source.end();
        ++ iter ) {
    if ( iter != source.begin() ) {
        results.push_back( separator );
    }
    results.insert( results.end(), iter->begin(), iter->end() );
}

Но вопрос в том, почему unsigned char? Предположительно, потому что вы форматирование в буфер для определенного протокола. Есть некоторые дополнительные требуется форматирование? Каков формат строки в вашем протоколе? (Как правило, это будет либо длина + данные, либо '\0' завершено.) Протокол требует какого-то выравнивания? (Для XDR & mdash; один из наиболее широко используемые протоколы & mdash; вам потребуется что-то вроде:

std::vector<unsigned char> results;
for ( std::vector<std::string>::const_iterator iter = source.begin();
        iter != source.end();
        ++ iter ) {
    size_t len = iter->size();
    results.push_back( (len >> 24) & 0xFF );
    results.push_back( (len >> 16) & 0xFF );
    results.push_back( (len >>  8) & 0xFF );
    results.push_back( (len      ) & 0xFF );
    results.insert( results.end(), iter->begin(), iter->end() );
    while ( results.size() % 4 != 0 ) {
        results.push_back( '\0' );
    }
}

, например.)

0 голосов
/ 22 февраля 2012

Повышенная сериализация должна позволить вам объединить структуру данных в последовательность unsigned char и восстановить ее снова.

0 голосов
/ 22 февраля 2012
std::vector<char> chars;
for (const std::string& s : strings)
{
    for (char c : s)
    {
        chars.push_back(c);
    }
    chars.push_back(',');
}

Немного неуклюже без нового синтаксиса цикла for, но вы поняли.

...