Печать std :: vector <char>без посторонних символов - PullRequest
0 голосов
/ 12 января 2020

Я создаю грубую замену gunzip с использованием библиотек Poco. Прямо сейчас дизайн должен прочитать gzipped файл (в настоящее время жестко запрограммированный в «data.gz») и распечатать вывод на стандартный вывод. Я очень близок, но у меня возникли некоторые проблемы с печатью некоторых дополнительных символов, как показано ниже.

Установка:

Ubuntu 19.10 с libpocofoundation62 (и всеми libpoco * 62), установленными через apt install libpoco-dev

Мой код на C ++, сильно смоделированный из https://github.com/pocoproject/poco/issues/1507

#define _GLIBCXX_USE_CXX11_ABI 0
#include <fstream>
#include <iostream>
#include <Poco/InflatingStream.h>
#include <Poco/String.h>
#include <vector>

using std::cout;
using std::endl;

int main() {

        cout.sync_with_stdio(false);
        std::ifstream istr("data.gz", std::ios::binary); // In the future will take filename as argument
        Poco::InflatingInputStream inflating_stream(istr, Poco::InflatingStreamBuf::STREAM_GZIP);
        std::vector<char> buf(16); // In the future will be larger, like 1024
        while (true) {
                inflating_stream.read(buf.data(), buf.size());
                size_t gcount = inflating_stream.gcount();

                if (!gcount && inflating_stream.eof()) {
                        inflating_stream.reset();
                }

                // This way outputs all the correct data, but also some extraneous characters at the end
                if (gcount) {
                        cout << buf.data();
                }

                /* This way works, but is slower
                if (gcount) {
                        for (auto i: buf) {
                                std::cout << i;
                        }
                }
                */

                else {
                        break;
                }
        }

        return 0;
}

My data.gz

$ zcat data.gz 
foo, bar
baz, qux
quux, quuz
corge, grault
garply, waldo
fred, plugh
xyzzy, thud

Моя команда компиляции :

g++ mygunzip.cpp -o /tmp/mygunzip -lPocoFoundation -lPocoUtil && chmod +x /tmp/mygunzip

Результат выполнения mygunzip:

$ /tmp/mygunzip
foo, bar
baz, qu��f�lUx
quux, quuz
cor��f�lUge, grault
garpl��f�lUy, waldo
fred, p��f�lUlugh
xyzzy, thud��f�lU
ugh
xyzzy, thud��f�lU

Итак, все правильные данные выводятся на печать, но в buf.data () после каждого посторонних данных прочитайте, что также распечатывается. Что было бы наиболее элегантным способом обработки посторонних данных? Я включил в комментарии еще один способ, который работает, и он распечатывает все правильные данные без посторонних символов. Но, похоже, это намного медленнее, поэтому я стараюсь улучшить другое решение, если это возможно.

1 Ответ

3 голосов
/ 12 января 2020

Вы дали cout a char* и сказали ему напечатать его.

Вы не просили его напечатать x char s, поэтому он обработал вещь как C -строка и продолжал идти, пока не встретил nullptr. Что еще он может сделать?

Вместо этого используйте cout.write(buf.data(), gcount).

...