我处于Python的幼虫阶段,而处于C++的预鸡蛋阶段,但是我正在努力做到最好,尤其是遵循“不要重复自己”的原则。

我有一个多通道原始文件格式要打开,带有一个主要的ascii头,其字段可表示为字符串和整数(始终编码为用空格填充的字符)。第二部分是N个 header ,其中N是主 header 的字段,并且这些 header 中的每个 header 本身都有许多文本和数字字段(编码为ascii),这些字段涉及实际的16位多通道流的长度和大小。组成文件的其余部分。

到目前为止,我在C++中有以下工作代码:

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <map>

using namespace std;

struct Header {
    string version;
    string patinfo;
    string recinfo;
    string start_date;
    string start_time;
    int header_bytes;
    string reserved;
    int nrecs;
    double rec_duration;
    int nchannels;
};

struct Channel {
    string label;
    string transducertype;
    string phys_dim;
    int pmin;
    int pmax;
    int dmin;
    int dmax;
    string prefiltering;
    int n_samples;
    string reserved;
};


int main()
{
    ifstream edf("/home/helton/Dropbox/01MIOTEC/06APNÉIA/Samples/Osas2002plusQRS.rec", ios::binary);

    // prepare to read file header
    Header header;
    char buffer[80];

    // reads header fields into the struct 'header'
    edf.read(buffer, 8);
    header.version = string(buffer, 8);

    edf.read(buffer, 80);
    header.patinfo = string(buffer, 80);

    edf.read(buffer, 80);
    header.recinfo = string(buffer, 80);

    edf.read(buffer, 8);
    header.start_date = string(buffer, 8);

    edf.read(buffer, 8);
    header.start_time = string(buffer, 8);

    edf.read(buffer, 8);
    stringstream(buffer) >> header.header_bytes;

    edf.read(buffer, 44);
    header.reserved = string(buffer, 44);

    edf.read(buffer, 8);
    stringstream(buffer) >> header.nrecs;

    edf.read(buffer,8);
    stringstream(buffer) >> header.rec_duration;

    edf.read(buffer,4);
    stringstream(buffer) >> header.nchannels;

    /*
    cout << "'" << header.version << "'" << endl;
    cout << "'" << header.patinfo << "'" << endl;
    cout << "'" << header.recinfo << "'" << endl;
    cout << "'" << header.start_date << "'" << endl;
    cout << "'" << header.start_time << "'" << endl;
    cout << "'" << header.header_bytes << "'" << endl;
    cout << "'" << header.reserved << "'" << endl;
    cout << "'" << header.nrecs << "'" << endl;
    cout << "'" << header.rec_duration << "'" << endl;
    cout << "'" << header.nchannels << "'" << endl;
    */

    // prepare to read channel headers
    int ns = header.nchannels; // ns tells how much channels I have
    char title[16]; // 16 is the specified length of the "label" field of each channel

    for (int n = 0; n < ns; n++)
    {
        edf >> title;
        cout << title << endl; // and this successfully echoes the label of each channel
    }


    return 0;
};

我已经必须做一些评论:
  • 我选择使用struct,因为格式规范非常硬编码。
  • 我没有遍历主 header 字段,因为在我看来,要读取的字节和类型的数量相当随意。
  • 现在,我成功地获得了每个通道的标签,我实际上将为每个通道的字段创建结构,这些结构本身可能必须存储在 map 中。

  • 我的(希望很简单)的问题是:

    “我是否应该担心偷工减料,以使这类代码更像Pythonic(更抽象,更少重复),或者这不是C++的工作方式吗?”

    许多Python传播者(就像我自己一样,因为我喜欢它)强调了它的易用性以及所有这些。因此,我会怀疑我是在做愚蠢的事情还是只是在做正确的事情,但是由于C++的本质,不是那么“自动”。

    谢谢阅读

    海尔顿

    最佳答案

    我会说没有Pythonic C++代码之类的东西。 DRY原理在两种语言中都适用,但是使用Python特定的构造,许多被认为是“Pythonic”的东西只是用Python表达逻辑的最短,最甜蜜的方式。惯用的C++完全不同。

    例如,lambda有时不被认为是Python风格的,并且保留给不存在其他解决方案的情况,而只是添加到C++标准中。 C++没有关键字参数,这是非常Pythonic的。 C++程序员在不需要时不喜欢构造map,而Python程序员可能会在很多问题上抛出dict,而这些问题恰好使意图比有效的替代方法更清晰。

    如果要保存键入,请使用the function I posted earlier,然后:

    header.version = read_field(edf, 8);
    header.patinfo = read_field(edf, 80);
    

    那应该节省您很多行。但是,比起那几行更为重要的是,您已经实现了少量的模块化:如何读取来读取字段,以及读取的字段现在已成为程序的独立部分。

    10-07 18:41