C++ 解析文件头

C++ 解析文件头,c++,C++,我正在处理图像。我想从标题中提取它的宽度和高度 宽度在位置处表示 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;

我正在处理图像。我想从标题中提取它的宽度和高度

宽度在位置处表示

  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循环

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

for(int i=index;i
std::cout
将打印作为字符传递的数据,如果数据是
char
,请在打印前尝试强制转换

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

cout您在读取文件后而不是之前查找文件的开头。您需要切换
read()
seekg()


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

大概是

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) { ... }

你没有提供太多的信息,所以这里有点猜测,但这是我阅读文件的方法:

主要功能是,不使用手动内存分配,使用
std::vector
(它的作用是什么)。还可以将数据从字符数组复制到从正确类型转换的变量中。这可以确保对齐正确(从不转换到字符数组中)。另一种方法可能是直接从文件读取正确类型的变量,并将其转换为
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';
}
intmain(int,char*argv[]
{
//第一个参数必须是文件名
std::string name=argv[1]?argv[1]:“”;
std::ifstream ifs(名称,std::ios::binary | std::ios::ate);//在末尾打开
如果(!ifs)
{

什么是
index
?你是说
for(inti=index;我从来没有使用过
新类型[count]
,改用
vector
。无论如何,你必须为你的问题提取一个最小的例子,以符合网站规则。ATM这是离题的。你有标题格式的链接吗?是高度和宽度的前两个值吗?文档是否告诉你“endian”是什么是用来存储数字的吗?图像是以原始格式存储的,偏移量4和4B是宽度,偏移量8和4B是高度。你知道图像是如何写出来的吗?你有任何关于该格式的文档吗?
int width, height;
stream >> width >> height;
while (stream >> width >> height) { ... }
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';
}