首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将二进制光栅文件转换为文本CSV

将二进制光栅文件转换为文本CSV
EN

Code Review用户
提问于 2018-07-18 20:12:10
回答 2查看 877关注 0票数 7

我有一个来自航天飞机雷达地形任务的二进制文件C1。它包含一个3601✕3601矩阵,存储为2字节大端整数.我的代码将它转换为一个可读的文本文件output.csv

我怎样才能让它变得更好?

这是我的代码:

代码语言:javascript
复制
#include 
#include 
using namespace std;

const int SRTM_SIZE = 3601;
static int height[SRTM_SIZE][SRTM_SIZE] = {{0},{0}};


int main() {


ifstream file("/storage/emulated/0/input.hgt", ios::in | ios::binary);

if(!file) {
cout << "Error opening file!" << endl;
return -1;
}

unsigned char buffer[2];


for (int i = 0; i < SRTM_SIZE; ++i) {

for (int j = 0; j < SRTM_SIZE; ++j) {

if(!file.read(reinterpret_cast(buffer), sizeof(buffer) )) {

    cout << "Error reading file!" << endl;

return -1; }

height[i][j] = (buffer[0] << 8) | buffer[1]; 

} }


ofstream meinFile;

meinFile.open ("/storage/emulated/0/output.csv");

    for(int x = 0; x < SRTM_SIZE; x++)
    { // from row 1 to row SRTM size

        for(int y = 0; y < SRTM_SIZE; y++)
        {// from column 1 to SRTM_Size

        meinFile << height[x][y] << ",";

        }

        meinFile << endl;
    }

            meinFile.close();
    cout<< "Gratulations!" <
EN

回答 2

Code Review用户

回答已采纳

发布于 2018-07-19 00:16:58

  • 避免 using namespace std.
  • 假设sizeof(int)为4,则height数组占用40 MB以上的空间。我明白,以现代标准来衡量,这是一个小小的改变,但一个好公民不应该要求太多,而不是真正需要的。我推荐一种类似流的处理:读取两个字节,转换它们,然后打印出来.这样,您只需要2字节的存储。
  • 程序用一个悬挂的逗号结束每一行。我不知道RFC怎么说。然而,考虑(int x= 0;x< SRTM_SIZE;x++) { for(int y= 1;y< SRTM_SIZE - 1;y++) { meinFile << height << ",";} meinFile <<身高<< std::endl;}
  • 你测试阅读错误。写作也可能失败。
  • 错误检测是非常重要的。错误报告也同样重要。不能打开文件-为什么?许可不足吗?文件没找到?腐败的媒体?看不懂文件-为什么?不能写文件-为什么?查看strerrorperror或类似的设施。
票数 6
EN

Code Review用户

发布于 2018-07-19 01:20:35

连同@vnp给出的答复:

我首先要说的是,缩进使得阅读变得非常困难,所以我将使用IDE提供的脚本/宏或能够提供正确缩进的程序。

在可能的情况下使用constexpr超过const任何声明为constexpr的内容都可以在编译时进行评估,从而提高运行时的性能。

更喜欢std::array而不是c-样式数组

std::array (在标头中)提供边界检查和其他一些有用的函数。

避免reinterpret_cast

这是依赖于平台的,可能会引起很多头痛。事实上,如果您必须使用reinterpret_cast,您可能需要重新分析您的代码,看看是否有更好的解决方案。

在您的例子中,我不太清楚为什么您声明了一个unsigned char数组,因为您无论如何都要将字节传输到int中。

关于字节排列(Endianness)

的注记

现在,您正在像读取big endian一样从文件中读取数据,这意味着最重要的字节位于第一位。现在,这没有什么问题,但是将来如果文件规范发生了变化,您可能希望有一个参数,或者一个参数,该参数指定文件中字节的排列方式。

通常,在处理二进制文件时,记住这一点是件好事。

使用std::cerr而不是std::cout来处理错误消息

在您的系统上,流可能指向相同的目的地,这些流可能由用户重新路由。通常,您希望分离用户界面和错误/日志记录输出。这在多线程控制台应用程序中可能变得更加重要。

关于您的方法的最后想法:

如果最终目标是简单地将二进制文件转换为csv,那么为什么要使用这么多内存来存储整个二进制文件呢?输入流和输出流可以同时存在,只要它们不指向相同的路径。这意味着,您可以在读取二进制文件时写入csv文件。下面是它的样子:

代码语言:javascript
复制
...
char buffer[2];
binary_file.read(buffer, sizeof(buffer));
csv_outut << ((buffer[0] << 8) | buffer[1]) << ',';
....
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/199776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档