打印 std::vector<char> 没有多余的字符
Print std::vector<char> without extraneous characters
我正在使用 Poco 库构建 gunzip 的粗略替代品。现在的设计是读取一个 gzip 文件(目前硬编码为 "data.gz")并将输出打印到标准输出。我已经很接近了,但是在打印一些额外的字符时遇到了一些麻烦,如下所示。
设置:
Ubuntu 19.10,通过 apt install libpoco-dev
安装了 libpocofoundation62(和所有 libpoco*62)
我的 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;
}
我的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() 中都保存着无关的数据,这些数据也被打印出来了。处理无关数据的最优雅方式是什么?我在评论中包含了另一种有效的方法,它打印出所有正确的数据,没有多余的字符。但它似乎慢得多,所以我希望尽可能改进其他解决方案。
你给了cout
一个char*
并告诉它打印它。
你没有要求它打印 x char
s,所以它把这个东西当作 C 字符串并继续打印,直到遇到 nullptr
。它还能做什么?
改用cout.write(buf.data(), gcount)
。
我正在使用 Poco 库构建 gunzip 的粗略替代品。现在的设计是读取一个 gzip 文件(目前硬编码为 "data.gz")并将输出打印到标准输出。我已经很接近了,但是在打印一些额外的字符时遇到了一些麻烦,如下所示。
设置:
Ubuntu 19.10,通过 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;
}
我的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() 中都保存着无关的数据,这些数据也被打印出来了。处理无关数据的最优雅方式是什么?我在评论中包含了另一种有效的方法,它打印出所有正确的数据,没有多余的字符。但它似乎慢得多,所以我希望尽可能改进其他解决方案。
你给了cout
一个char*
并告诉它打印它。
你没有要求它打印 x char
s,所以它把这个东西当作 C 字符串并继续打印,直到遇到 nullptr
。它还能做什么?
改用cout.write(buf.data(), gcount)
。