1

可能重复:
为什么在读取 eof 时设置故障位?有出路吗?

我正在编写一个小程序,它在 Mac OS 和 Ubuntu (Unix ...) 上运行良好。程序必须读取数据文件并将字节(chars / unsigned chars)和memcpy()它们分离成浮点数。这将包括获取以下四个值的过程,读取并将它们左移到 32 位int,然后将ints 内存复制到float. 像这样:

0x43 0x66 0x1A 0x79 -> 将 int32 和 memcpy() 读入 float -> val = 230.103

正如我所说,这适用于 Unix,但 Windows 似乎将其解释char 0x1A为文件结尾 (EOF) 错误并停止读取数据。为什么 Windows 做这样的事情而不是 Unix?我怎么能把它关掉?

我什至通过查看ifstream自身并检查是否设置了 EOL 标志来尝试错误处理。然后我会clear()'ifstream的错误标志并继续阅读(使用get()),但该死的东西总是返回相同的 EOF /0x1A字符并且不会读取下一个字符。

编辑:添加了一些代码


ifstream input (PATH, ios::in);
if (input.is_open()) {
  unsigned int counter = 0;
  while (input.good()) {
    BYTE byte;
    byte = input.get();
    printf("%i, ", byte);
    counter++;
  }
  printf("\r%i, ", counter);
  input.close();
} else {
  printf("Can't open file!");
}

很感谢任何形式的帮助。

最大限度

4

2 回答 2

6

使用ifstream input (PATH, ios::in);,您以(默认)文本模式打开文件。当以文本模式打开文件时,标准库对从文件读取的数据执行特定于平台的转换,以将平台的文本文件本机格式映射到 C(和 C++)对文本文件的视图。

对于类 unix 系统(包括 Mac OSX 和 Linux),本机文本格式与 C 和 C++ 查看文本的方式相同,因此不需要转换。

在 Windows 平台上,必须转换行尾('\n'转换为字符序列和从字符序列转换),并且必须解释CR LFWindows 定义的 EOF 字符 ( )。1A

在其他系统上,可能需要更广泛的转换(例如,如果将文本文件指定为正好 80 个字符的空格填充行,则实现必须'\n'在读取 80 个字符后自己生成一个字符,并且它可能会抑制一行中的尾随空格字符)。

于 2012-11-27T11:52:59.190 回答
1

带有 ios::binary 标志:

#include <iostream>
#include <fstream>
#include <windows.h>

int main()
{

    std::ifstream input ("msg.txt",  std::ios::binary );
    if (input.is_open())
    {
        unsigned int counter = 0;
        while (input.good()) 
        {
            BYTE byte;
            byte = input.get();
            printf("%d : %d \n", counter,  byte);
            counter++;
        }

        input.close();
    }
}

输入数据 :0x43 0x66 0x1A 0x79 0x68 0xAc

输出 :

0 : 48 
1 : 120 
2 : 52 
3 : 51 
4 : 32 
5 : 48 
6 : 120 
7 : 54 
8 : 54 
9 : 32 
10 : 48 
11 : 120 
12 : 49 
13 : 65 
14 : 32 
15 : 48 
16 : 120 
17 : 55 
18 : 57 
19 : 32 
20 : 48 
21 : 120 
22 : 54 
23 : 56 
24 : 32 
25 : 48 
26 : 120 
27 : 65 
28 : 99 
29 : 32 
30 : 255

在此示例中,数据是按字符读取的,但您可以使用ifstream.read(buffer, buffersize).

顺便说一下,这个程序是在Windows7上用gcc编译的

于 2012-11-27T11:36:42.450 回答