【问题标题】:Not able to read whole file无法读取整个文件
【发布时间】:2013-04-05 17:31:58
【问题描述】:

我正在制作一个 C++ 程序,以便能够打开 .bmp 图像,然后能够将其放入 2D 数组中。现在我有这样的代码:

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "Image.h"
using namespace std;

struct colour{
    int red;
    int green;
    int blue;
};

Image::Image(string location){

    fstream stream;
    string tempStr;

    stringstream strstr;
    stream.open(location);

    string completeStr;

    while(!stream.eof()){
        getline(stream, tempStr);
        completeStr.append(tempStr);
    }
    cout << endl << completeStr;

    Image::length = completeStr[0x13]*256 + completeStr[0x12];
    Image::width = completeStr[0x17]*256 + completeStr[0x16];
    cout << Image::length;
    cout << Image::width;
    cout << completeStr.length();

    int hexInt;
    int x = 0x36;
    while(x < completeStr.length()){
        strstr << noskipws << completeStr[x];
        cout << x << ": ";
        hexInt = strstr.get();
        cout << hex << hexInt << " ";
        if((x + 1)%3 == 0){
            cout << endl;
        }
        x++;
    }
}

现在,如果我在我的 256x256 测试文件上运行它,它会打印得很好,直到它到达 0x36E 并给出错误/不会进一步。这是因为 completeStr 字符串没有接收到 bmp 文件中的所有数据。为什么无法读取 bmp 文件中的所有行?

【问题讨论】:

标签: c++ file iostream fstream bmp


【解决方案1】:

您的代码存在许多问题。校长 一个(可能是你的问题的原因)是你是 以文本模式打开文件。从技术上讲,这意味着如果 该文件包含除可打印字符和一些 特定的控制字符(如'\t'),你有未定义 行为。实际上,在 Windows 下,这意味着序列 0x0D, 0x0A 将被转换为单个'\n',并且 0x1A 将被解释为文件的结尾。并不真地 读取二进制数据时想要什么。你应该打开 以二进制模式流式传输 (std::ios_base::binary)。

不是一个严重的错误,但你不应该真的使用fstream 如果您只是要读取文件。事实上,使用一个 fstream 应该非常罕见:您应该使用 ifstreamofstreamstringstream 也是如此(但 在读取二进制文件时,我看不到 stringstream 的任何作用 文件)。

另外(这是一个真正的错误),您正在使用的结果 getline 不检查是否成功。通常 阅读台词的成语是:

while ( std::getline( source, ling ) ) ...

但是像stringstream,你想使用getline 二进制流;它将删除所有 '\n' (其中有 已经从 CRLF 映射)。

如果你想要内存中的所有数据,最简单的解决方案是 类似:

std::ifstream source( location.c_str(), std::ios_base::binary );
if ( !source.is_open() ) {
    //  error handling...
}
std::vector<char> image( (std::istreambuf_iterator<char>( source ) ),
                         (std::istreambuf_iterator<char>()) );

【讨论】:

  • 谢谢!我是一名试图转向 C++ 的 Java 程序员。从二进制文件中提取到文件大小,然后创建一个具有该大小的数组不是更快吗?假设向量比数组慢,因为它需要调整大小。
  • @user2250025 可能有点。不过,在我看来,他好像在进行图像处理,但我不认为差异很大。更不用说找出文件大小的便携式方法,如果您开始接受非便携式结构,mmap 会明显更快。
【解决方案2】:

std::getline 读入一行文本。

对二进制文件没用。

以二进制模式打开文件并使用未格式化的输入操作(如read)。

【讨论】:

    猜你喜欢
    • 2022-01-09
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    相关资源
    最近更新 更多