2016-03-19 133 views
0

我正在处理图片。我想从标题中提取它的宽度和高度。解析文件头文件

宽度在位置

size 
    4B width 
    4B height 

它们在特定指数表示来表示。

我试图解析它并与代码

ifstream f(name, ios::binary | ios:: in); // reading a file in binary 
    ostringstream ob; 

    if (f.fail()){ // fail test 
     return false; 
    } 

    f.seekg (0, f.end); 
    int length = f.tellg(); // length of the file 
    memory = new char[length]; // allocate array of chars 
    f.read (memory, length); // read the content of the file into an array 
    f.seekg (0, f.beg); // point back at the beginning of the file. 

他们每个人都有4B提取它,因此,使用用于循环

for (int i = index ; i <4 ;i++){ 
    cout << hex<< memory[i]; 
} 

或我什它使用它转换成数

string a; 
    for (int i = index; i < 4 ;i++{ 
     a+=memory[i]; 
    } 
    cout << atoi(a.c_str()) << endl; 

应输出一个数字,但它输出一些不可读的格式。

+0

什么是'索引'?你是指'for(int i = index; i MikeCAT

+2

切勿使用'new type [count]',而应使用'vector '。无论如何,你将不得不为你的问题提取一个最小的例子来符合网站规则。 ATM它是无关紧要的。 –

+0

你有链接到标题的格式吗?它的前两个值是高度和宽度吗?文档是否告诉你什么“endian”用于存储数字? – Galik

回答

0

std::cout将打印作为字符传递的数据,如果数据为char,请在打印前尝试投射。

for (int i = 0 ; i < 4 ; i++) { 
    cout << hex<< (int)(unsigned char)memory[index + i]; 
} 

如果文件的数量是小端,它可以被转换成整数是这样的:

// Use #include <cstdint> for using type uint32_t and uint8_t 
uint32_t num = 0; // the converted number will be here 
for (int i = 0 ; i < 4 ; i++) { 
    num |= (uint8_t)memory[index + i] << (uint32_t)(8 * i); 
} 
4

你正在寻找的文件后开始读它,而比以前。你需要切换轮read()seekg()

f.seekg (0, f.beg); // point back at the beginning of the file. 
f.read (memory, length); // read the content of the file into an array 
1

对于标题中所述问题的快速回答,并通过查看输入文件指定,你可以简单地看了三线,跳过第一然后从下面两行中提取一个整数。

因此,像

int width, height; 

std::string input; 
std::istringstream is; 

std::getline(stream, input); // One line for the "size" string 

std::getline(stream, input); // One line for the width 
is.str(input) 
is >> width; 

std::getline(stream, input); // One line for the height 
is.str(input) 
is >> height; 

如果你在文件中的多个条目是这样,然后做上述的一个循环。

如果该文件实际上并不包含你显示文本,只是数字,那么它的更简单:

int width, height; 
stream >> width >> height; 

或者,如果你有多个条目

while (stream >> width >> height) { ... } 
2

你不提供非常多的信息继续下去,所以这里有一点猜测,但这是我可能会如何读取文件:

主要特点是,不要使用手动内存分配,使用std::vector(它的用途)。同时将char数组中的数据复制到正确类型的变量中。这确保对齐是正确的(从未投入字符数组)。另一种方法可能是直接从文件中读入正确类型的变量char*

int main(int, char* argv[]) 
{ 
    // first parameter needs to be file name 
    std::string name = argv[1] ? argv[1]:""; 

    std::ifstream ifs(name, std::ios::binary|std::ios::ate); // open at end 

    if(!ifs) 
    { 
     std::cerr << std::strerror(errno) << '\n'; 
     return EXIT_FAILURE; 
    } 

    if(ifs.tellg() < 8) // too small 
    { 
     std::cerr << "Bad image file, too short" << '\n'; 
     return EXIT_FAILURE; 
    } 

    // Don't allocate memory manually, use a container 
    std::vector<char> image(ifs.tellg()); // big enough for whole file 

    ifs.seekg(0); // back to beginning 

    if(!ifs.read(image.data(), image.size())) 
    { 
     std::cerr << std::strerror(errno) << '\n'; 
     return EXIT_FAILURE; 
    } 

    // copy raw data into variables 

    std::uint32_t width; // 4 bytes wide integer 
    std::uint32_t height; // 4 bytes wide integer 

    std::copy(&image[4], &image[ 8], (char*)&width); // offset 4 bytes 
    std::copy(&image[8], &image[12], (char*)&height); // offset 8 bytes 

    // at this point a lot depends on the system architecture and 
    // how the number is stored in the file. The documentation 
    // should tell you if it is little-endian or big-endian 

    // you may have to do manual jiggery-pokery 
    // to change endienness 

    std::cout << "width : " << width << '\n'; 
    std::cout << "height: " << height << '\n'; 
}