【问题标题】:c++ cout instead of fstreamc++ cout 代替 fstream
【发布时间】:2014-10-28 19:03:54
【问题描述】:

通常我生活在我的 C# 世界中。但有时我必须爆发并在外面做点什么。

目前我必须解码音频流,并且必须直接在我的 c++ 控制台应用程序中输出。

如果我将内容写入文件,我可以听到正确的结果。 但如果我使用 fstream cout 而不是,我只会听到嘈杂的声音。

我必须如何正确地做到这一点? 这里是工作文件流代码:

fstream wavefile;
wavefile.open(output, ios::out | ios::binary | ios::trunc);

//do something
wavefile.write((char*) &waveheader, waveheadersize);
//do something else
do {
        //do something
        //decodedBuffer is of type BYTE* , decodedLength is of type DWORD
        wavefile.write((char*) decodedBuffer, decodedLength);
        wavefile.flush();
    } while (encodedLength > 0);

我不工作的 cout 代码:

std::cout.setf(ios::out | ios::binary | ios::trunc);

//do something
//this works, I got the same output
cout << structToString(&waveheader) << endl;
//do something else
do {
        //do something
        cout << (char *)decodedBuffer;
    } while (encodedLength > 0);

提前致谢

【问题讨论】:

  • 使用std::cout时将输出重定向到文件并进行比较
  • ios::outios::binaryios::trunc 都不是格式化标志。见en.cppreference.com/w/cpp/io/ios_base/setf
  • 您需要包含实际的错误消息,以使其成为有效问题。 “无效的代码”太含糊了。
  • 让我猜猜,您在 Windows 上,因此您的流上的文本模式翻译正在扼杀您的数据。
  • 即使是这样,cout &lt;&lt; (char *)decodedBuffer 也会调用格式化的输出插入器。你知道std::cout 仍然有一个write 方法,对吧?它的行为类似于unformatted output function,这可能是您想要的(实际上在使用std::basic_ostream::writestd::fstream 写入操作中使用)。

标签: c++ fstream cout


【解决方案1】:

首先,绝对没有理由为std::fstreamstd::cout 使用不同的代码(除此之外,您的cout 代码使用格式化输出,而且错误):

在这两种情况下,您都在使用他们的ostream-interface。

所以,首先,修复第二个代码(尽可能)用第一个替换它。


现在,我们来看看一个区别(您试图用setf 掩盖):std::cout 处于文本模式,而不是二进制模式

很遗憾,ios::outios::binaryios::trunc 都不是格式化标志,因此您不能使用 setf 设置它们。

实际上,模式在事后根本无法更改(至少不可移植)。

幸运的是,您可以简单地忽略许多系统上的错误模式,因为 Linux 和其他系统将文本模式和二进制模式等同起来。在 Windows 上,这个 hack 应该可以帮助您解决问题:

cout.flush();
fflush(stdout);
_setmode(_fileno(stdout), _O_BINARY);

【讨论】:

    【解决方案2】:

    简单的答案是你不能。你需要输出 二进制模式。选择模式,一劳永逸,当你 打开文件,std::cout 始终以文本模式打开。

    既然你只是写一个字节块,最简单的 解决方案是使用系统级请求。在 Windows 下, 例如,您可以使用GetStdHandle( STD_OUTPUT_HANDLE ) 得到标准输出的句柄,然后WriteFile 写一个块 字节数。 (在 Unix 下,标准的文件描述符 out 始终为1,函数为write。但自从有了 Unix下的文本模式和二进制模式没有区别, 我认为这不是你的情况。)

    【讨论】:

    • 当然也值得考虑直接使用原始 OS-API,尽管我猜他想继续使用ostream-interface。
    • @Deduplicator 出于可移植性的原因也许可以理解,但由于没有可移植的解决方案......
    【解决方案3】:

    试试这个,

        std::cout.write(reinterpret_cast<char*>(decodedBuffer), decodedLength);
    

    但我不确定 structToString(&waveheader) 是否正常工作,但您似乎可以接受。

    【讨论】:

    • 他要的是输出一块内存,从decodedBuffer开始,长度是decodedLength。不是数据的字符串表示形式。
    • 是的。但是cout是文本模式,所以他的数据还是会乱码。
    • 最后我混合使用了@Deduplicator 和 user3183610。所以它没有那么糟糕。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多