2013-04-05 56 views
0

我正在製作一個C++程序,以便能夠打開一個.bmp圖像,然後能夠將它放入二維數組中。現在,我有這樣的代碼:無法讀取整個文件

#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++; 
    } 
} 

,如果我現在對我的256×256的測試文件運行這個將打印精細,直到它到達0x36E它給出了一個錯誤/不走的更遠。發生這種情況是因爲completeStr字符串不會收到bmp文件中的所有數據。爲什麼不能讀取bmp文件中的所有行?

+3

''時爲[車和錯誤(HTTP(EOF()!)://計算器。 COM /問題/ 5605125 /爲什麼 - 是 - iostreameof-內,一個循環條件考慮的,是錯誤的)。如果這是您的問題,我不會感到驚訝。 – chris 2013-04-05 17:32:18

+1

您可能會考慮將位圖讀取爲二進制文件,而不是線條集合。 – 2013-04-05 17:37:24

+0

[讀取文件到C++中的字符串]可能的重複(http://stackoverflow.com/questions/3286822/reading-a-file-to-a-string-in-c) – 2013-04-05 17:45:20

回答

3

您的代碼有許多問題。主要的 之一(也可能是你的問題的原因)是,你是 在文本模式下打開文件。從技術上講,這意味着如果 該文件包含除可打印字符和幾個 特定控制字符(如'\ t')以外的任何文件,則表明您有未定義的 行爲。實際上,在Windows下,這意味着0x0D,0x0A的序列 將被轉換爲單個'\n',並且該0x01A將被解釋爲該文件的結尾。不是真的 閱讀二進制數據時需要什麼。您應該以二進制模式打開 流(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>())); 
+0

謝謝!我是一名Java程序員,試圖轉移到C++。從二進制文件中提取文件大小,然後製作一個大小的數組不是更快?假設矢量比數組慢,因爲它需要調整大小。 – Marckvdv 2013-04-06 12:44:22

+0

@ user2250025可能略微。儘管如此,這聽起來像是他正在進行圖像處理,而且我不會想到這種差異是顯着的。更不用說沒有找到文件大小的便攜式方法,並且如果您開始接受不可移植的構造,「mmap」顯着更快。 – 2013-04-06 18:56:18

2

std::getline讀入一行文字。

對二進制文件沒用。

以二進制模式打開文件並使用無格式輸入操作(如read)。