【问题标题】:Why does this Stream of data end at byte 26?为什么这个数据流在字节 26 结束?
【发布时间】:2011-06-06 22:38:18
【问题描述】:

我仍在处理一周前的位图 I/O 问题。我又被卡住了,所以我决定从一种熟悉的 I/OI 开始,让它更像我需要的稳定(一次检查每个字节(像素)并基于它输出到文件字节的值)。

我从一个程序开始,它读取并检查文本文件的每个字符,如果高于某个阈值则输出一个“Z”,如果低于某个阈值则输出一个“A”。

该程序运行良好,因此我决定将其从文件中的字符更改为字节。

现在,我一直遇到问题。文件的前 26 个(字节 0-25)字节是正确的,但其余为 0 或 -1,这取决于我使用的是 ifstream.get() 还是 ifstream.read

输入文件Input.FILE 是在十六进制编辑器中创建的,只包含0x00-0xFF。长度为 256 字节。

代码:

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main()
{
   ifstream sourcefile;
   ofstream output;
   ofstream output2;

   output.open("output.txt");
   output2.open("messages.txt");
   sourcefile.open("Input.FILE");

   vector<char> data(256);
   sourcefile.read(&data[0],256);
   sourcefile.seekg(0,ios::beg);

   for(int i = (int) 0x00 ; i < data.size() ; i++)
   {
      output2 << "Value data[" << i << "] = " << (int) data[i] << endl;

      if((int)data[i] < 0)
      {
         // since I can't make an unsigned char vector, I use this to convert
         // it to the correct number. Could this be the problem?
         data[i] = 256 + data[i];
         output2 << "less than zero." << endl;
      }

      if(data[i] > 64)
      {
         data[i] = 0xFF;
         output2 << "greater than 64, set to 0xFF." << endl;
      }
      else if(data[i] < 64)
      {
         data[i] = 0x00;
         output2 << "less than 64, set to 0x00." << endl;
      }
      else
      {
         // This is most likely pointless, but I didn't want to take a chance
         data[i] = 0x75;
         output2 << "neither greater nor less than 64? Set to 0x75." << endl;
      }

      output2 << endl;
   }

   output.write(&data[0],256);
}

输出(来自message.txt):

注意:data[0-25] 包含正确的值

...
数值数据[19] = 19 小于 64,设置为 0x00。
数值数据[20] = 20 小于 64,设置为 0x00。
值 data[21] = 21 小于 64,设置为 0x00。
数值数据[22] = 22 小于 64,设置为 0x00。
数值数据[23] = 23 小于 64,设置为 0x00。
数值数据[24] = 24 小于 64,设置为 0x00。
数值数据[25] = 25 小于 64,设置为 0x00。
value data[26] = 0 小于 64,设置为 0x00。

【问题讨论】:

  • 您可以使用 Iostream 库的错误标志来找到出现问题的确切点。
  • 这是一个很好的建议,但错误标志对我没有多大帮助。

标签: c++ vector fstream


【解决方案1】:

以二进制模式打开您的流:

sourcefile.open("Input.FILE", ios::binary);

【讨论】:

  • 效果很好!为什么这很重要?无论哪种方式,它都只是十六进制数据。
  • 十六进制数据在解释为文本数据时可能会由于文件结束 (EOF) 终止字符而提前结束。当流以二进制形式打开时,文件被完全读取。
【解决方案2】:

如果您查看 ascii code 25 is 的含义,您会发现它的意思是 end of medium,因此很有可能如果您在 ascii 模式下阅读,任何后续阅读都将无法正常工作。

尝试指定您使用的是二进制文件:

sourcefile.open("Input.FILE", ios::binary);

【讨论】:

  • 我忘记了 EOF 字符。既然您似乎先回答了第二个问题,我会给您最好的答案。
  • @jaffe:它与 ASCII 无关。您在 Windows 中遇到 C/C++“文本模式”,其中 ^Z (Ctrl Z, ASCII 26) 标记文本文件中数据的结尾。我记得这源于 CP/M 中的类似行为,可能具有不同的控制特征。您可以通过“type con”等命令在命令解释器中测试该行为,并在一行中首先使用 Ctrl Z 终止输入,然后是换行符。在任何控制台窗口中,您还可以在 F6 功能键上使用 Ctrl Z。
  • 我之前在控制台中按过 Ctrl+Z,以为它会撤消,但我得到了那个 ^Z 字符。现在我知道那是什么了,谢谢。如果我没记错的话,这种行为也在 linux 中。
【解决方案3】:

试试sourcefile.open("Input.FILE", std::ifstream::binary)

【讨论】:

    【解决方案4】:

    也许您是 1) 使用过时的操作系统(例如 CP/M 或 DOS),其中内嵌 control-Z 表示 EOF,以及 2) 未以二进制模式打开文件。

    试试sourcefile.open("Input.FILE", ios::binary);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 2017-04-18
      • 1970-01-01
      • 2013-04-18
      • 2020-01-17
      相关资源
      最近更新 更多