std :: cout<< stringstream.str() - > c_str()不打印任何内容

时间:2010-12-02 19:52:45

标签: c++ stringstream stdstring libpcap unsigned-char

在一个函数中,得到unsigned char&& unsigned char length,

void pcap_callback(u_char *args, const struct pcap_pkthdr* pkthdr, const u_char* packet) 
{
    std::vector<unsigned char> vec(packet, packet+pkthdr->len); // optimized from foo.
    std::stringstream scp;
    for (int i=0;i<pkthdr->len;i++) {
        scp<<vec[i];
    }
    std::string mystr =  std::string(scp.rdbuf()->str());
    std::cout << "WAS: " << packet << std::endl;
    std::cout << "GOOD: " << scp.str() << std::endl;
    std::cout << "BAD: "  << scp.str().c_str() << std::endl;
    std::cout << "TEST: " << mystr.size() << std::endl;
    assert(mystr.size() == pkthdr->len); 
}

结果:

  • WAS:什么都不打印(猜猜有一个指向const ..的情况)
  • GOOD:打印数据
  • BAD:什么都不打印
  • TEST,断言:打印mystr.size()等于传递unsigned char size。

我试过了:

  • string.assign(scp.rdbuf());
  • memcpy(char,scp.str(),10);
  • 创建/分配临时字符的不同方法,字符串

没有帮助..想要获得包含数据的 std :: cout 'able std :: string (来自 foo) ,它是 unsigned char ,它是数据包数据。)

猜测原始的 foo 可能不会以空终止,或问题是这样的 - 简单,但无法进入..这里有什么要寻找的东西?< / p>

(此代码是另一种尝试使用libpcap,只是以C ++方式打印数据包,而不使用像libpcapp这样的已知C ++魔术包装。)

3 个答案:

答案 0 :(得分:3)

要进行快速测试,请检查scp.str().size() == strlen(scp.str().c_str())以查看字符串中是否嵌入了'\ 0'字符,这是我怀疑的情况。

答案 1 :(得分:2)

我认为你这是错误的做法。看起来你在这里处理二进制数据,在这种情况下你不能期望有意义地将它作为文本输出到屏幕。你真正需要的是一个十六进制转储

const unsigned char* ucopy = packet;
std::ios_base::fmtflags old_flags = std::cout.flags();
std::cout.setf(std::ios::hex, std::ios::basefield);

for (const unsigned char* p = ucopy, *e = p + pkthdr->len; p != e; ++p) {
    std::cout << std::setw(2) << std::setfill('0') << static_cast<unsigned>(*p) << " ";
}

std::cout.flags(old_flags);

这将逐字节输出数据,并让您检查二进制数据的各个十六进制值。空字节将简单地输出为00

答案 2 :(得分:1)

输出尝试失败后检查std::cout.good()。我的猜测是输出有一些失败(即尝试将不可打印的字符写入控制台),这是在failbit上设置cout

同时检查以确保字符串不以NULL开头,这会导致空输出成为预期的行为:)

(旁注,如果您使用的是C ++,请reinterpret_cast使用unsigned char *ucopy = (unsigned char*)packet;;)