Собственный способ C ++ для упаковки и распаковки строк - PullRequest
2 голосов
/ 26 марта 2009

После моего более раннего вопроса . Есть ли способ написать строку в сжатой / битной версии, используя родную идиому C ++. Я думаю что-то вроде родного Perl упаковать и распаковать .

Ответы [ 2 ]

2 голосов
/ 27 марта 2009

Основываясь на прочтении вашего предыдущего вопроса, я думаю, что вы хотите сказать, что вы хотите двоичный кодированный вывод, а не "сжатый" вывод. Как правило, «сжатый» используется для конкретной ссылки на данные, размер которых был уменьшен благодаря применению алгоритма, такого как кодирование LZW. В вашем случае вы можете обнаружить, что выходные данные «сжаты» в том смысле, что они меньше, потому что для большого числа чисел двоичное представление более эффективно, чем представление ASCII, но это не «сжатие» в стандартном смысле Возможно, именно поэтому у вас возникли проблемы с получением ответа, который вы ищете.

Я думаю, вы действительно спрашиваете следующее:

Учитывая число в формате ASCII (например, сохраненное в std :: string), как я могу записать это в файл в виде двоичного целого числа кодирования?

Ответ состоит из двух частей. Во-первых, вы должны преобразовать строку в кодировке ASCII в целочисленное значение. Вы можете использовать функцию, такую ​​как strtol, которая будет возвращать длинное целое число, эквивалентное по значению вашему закодированному числу ASCII. Имейте в виду, что существуют ограничения по величине числа, которое может быть представлено в виде длинного целого числа, поэтому, если ваши числа очень и очень велики, вам, возможно, придется проявить больше изобретательности при их переводе.

Во-вторых, вы должны записать данные в выходной поток с помощью ostream :: write (), который не пытается отформатировать байты, которые вы передаете. Если вы просто используете потоковую операцию оператора << () по умолчанию для записи значений, вы обнаружите, что ваши числа просто переводятся обратно в ASCII и записываются таким образом. Соберите все это так: </p>

#include <stdlib.h>        // For strtol().
#include <arpa/inet.h>     // For htonl().
#include <fstream>         // For fstream.
#include <string>          // For string.

int main(int argc, char *argv[]) {
    char *dummy = 0;
    std::string value("12345");

    // Use strtol to convert to an int; "10" here means the string is 
    // in decimal, as opposed to, eg, hexadecimal or octol, etc.

    long intValue = strtol(value.c_str(), &dummy, 10);

    // Convert the value to "network order"; not strictly necessary, 
    // but it is good hygiene.  Note that if you do this, you will 
    // have to convert back to "host order" with ntohl() when you read 
    // the data back.

    uint32_t netValue = htonl(intValue);

    // Create an output stream; make sure to open the file in binary mode.

    std::fstream output;
    output.open("out.dat", std::fstream::out | std::fstream::binary);

    // Write out the data using fstream::write(), not operator<<()!

    output.write(reinterpret_cast<char *>(&netValue), sizeof(netValue));
    output.close();
}
2 голосов
/ 26 марта 2009

Если ничего другого, я считаю, что вы всегда можете сложить заголовки и библиотеки perl. Смотрите perlguts .

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