【问题标题】:How can I handle packed data from Perl/PHP in C++?如何在 C++ 中处理来自 Perl/PHP 的打包数据?
【发布时间】:2011-01-10 22:11:23
【问题描述】:

我在 C++ 中实现 PHP 程序时遇到问题。它是关于 PHP/Perl 函数unpack。我不知道如何在 C++ 中执行以下操作(读取文件没有问题......但是我如何解压缩(“C*”)读取的内容)。

<?php
$file = fopen("bitmaskt.dat", "rb");
//create the data stream
$matrix_x           = unpack("C*", fread($file, 286));
$matrix_y           = unpack("C*", fread($file, 286));
$mask_data          = unpack("C*", fread($file, 286));
$reed_ecc_codewords = ord(fread($file, 1));
$reed_blockorder    = unpack("C*", fread($file, 128));
fclose($file);
?>

目前,我自己解决这个问题非常绝望 - 我正在寻找几天,我发现的都是问题......那里有免费的 unpack() c++ 实现吗? :-(

【问题讨论】:

    标签: php c++ perl unpack pack


    【解决方案1】:

    Perl 的documentation for pack 涵盖了用于packunpack 的模板。

    假设你生成了bitmaskt.dat

    #! /usr/bin/perl
    
    use warnings;
    use strict;
    
    open my $fh, ">", "bitmaskt.dat" or die "$0: open: $!";
    
    my @data = (42) x 286;
    
    print $fh pack("C*" => @data);
    print $fh pack("C*" => @data);
    print $fh pack("C*" => @data);
    print $fh pack("C"  => 7);
    print $fh pack("C*" => (1) x 128);
    
    close $fh or warn "$0: close";
    

    你可以阅读它

    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <vector>
    
    typedef unsigned char datum_t;
    typedef std::vector<datum_t> buf_t;
    
    std::istream &read_data(std::istream &in, buf_t &buf, size_t n)
    {
      std::istreambuf_iterator<char> it(in.rdbuf()), eos;
      while (it != eos && n-- != 0)
        buf.push_back(static_cast<datum_t>(*it++));
    
      return in;
    }
    

    例如:

    int main()
    {
      std::ifstream bm("bitmaskt.dat", std::ifstream::binary | std::ifstream::in);
    
      struct {
        buf_t buf;
        size_t len;
        std::string name;
      } sections[] = {
        { buf_t(), 286, "matrix_x" },
        { buf_t(), 286, "matrix_y" },
        { buf_t(), 286, "mask_data" },
        { buf_t(),   1, "reed_ecc_codewords" },
        { buf_t(), 128, "reed_blockorder" },
      };
      const int n = sizeof(sections) / sizeof(sections[0]);
    
      for (int i = 0; n - i > 0; i++) {
        if (!read_data(bm, sections[i].buf, sections[i].len)) {
          std::cerr << "Read " << sections[i].name << " failed" << std::endl;
          return 1;
        }
      }
    
      const int codeword = 3;
      std::cout << (unsigned int) sections[codeword].buf[0] << '\n';
    
      return 0;
    }
    

    输出:

    7

    【讨论】:

      【解决方案2】:

      我不知道 C++ 的 unpack 的任何一般实现,但这似乎不是您需要的东西。

      如果 matrix_x 在某处定义为 unsigned char matrix_x[286] 并且您有一个打开的输入流 inFile 那么你需要做的是inFile.get(matrix_x, 286)。这会从输入中读取 286 个字节,并将它们放入 matrix_x 指向的数组中。

      【讨论】:

      • 嗨,多维数据集,谢谢您的回答,但是在matrix_x 中存在二进制“废话”,而不是我通过unpack("C*") 在 PHP 和 Perl 中获得的数字。 "bitmaskt.dat" 是在 Perl 中使用 pack("C*") 创建的。我尝试了一下,将matrix_x 的每个元素类型转换为long int 似乎与PHP 的 unpack("C*") 具有相同的效果 - 任何人都可以确认这一点吗?
      • 我不太明白你是如何输入数字的。你能展示那部分 C++ 代码吗?
      猜你喜欢
      • 1970-01-01
      • 2019-11-21
      • 2015-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      相关资源
      最近更新 更多