C++ 高效、干净地编写ofstream/fstream对象,用于编写带有标题的表

C++ 高效、干净地编写ofstream/fstream对象,用于编写带有标题的表,c++,stream,ascii,fstream,organization,C++,Stream,Ascii,Fstream,Organization,在努力成为一名真正优秀的专业程序员的过程中,我遇到了一些情况,无论我做什么,代码总是看起来很凌乱,我没有使用我的函数式编程技能和面向对象编程技能来编写一个好的、有组织的代码,而没有重复的模式,我今天正试图解决这样一个问题 因此,我有一个控制台/终端程序,它可以测量来自许多设备的许多内容,并且输出是一个ASCII表,该表将发送到一个文本文件。我关心的是:如何以最灵活、最专业的方式传递这些信息 因此,我将输出的标题写如下(名称、单位和数据类型的三行标题): 流输出流的(“output.txt”,st

在努力成为一名真正优秀的专业程序员的过程中,我遇到了一些情况,无论我做什么,代码总是看起来很凌乱,我没有使用我的函数式编程技能和面向对象编程技能来编写一个好的、有组织的代码,而没有重复的模式,我今天正试图解决这样一个问题

因此,我有一个控制台/终端程序,它可以测量来自许多设备的许多内容,并且输出是一个ASCII表,该表将发送到一个文本文件。我关心的是:如何以最灵活、最专业的方式传递这些信息

因此,我将输出的标题写如下(名称、单位和数据类型的三行标题):

流输出流的
(“output.txt”,std::ios::out);

outputStream您可以在这里使用多态性:定义基类

struct quantity {
    virtual std::string name();
    virtual std::string unit();
    virtual std::string datatype();

    virtual std::string measurement();
}
并为每个数量定义具有适当实现的派生类


然后,你可以有一个
std::vector q
和标题和测量值的打印成为一个简单的循环
q

对于第一个问题,建议将标签打印封装在函数中:

1) 将列名存储在常量
std::array
std::vector

#包括

const std::vector col_label1={“col_label1,col_label2,col_label3”}

因此,您可能会得到如下结果:

void printHeaders(std::ofstream& outputStream){
    const std::vector<std::string> col_labels = {"col_label1", 
                                                "col_label2", 
                                                "col_label3"};
    for(auto& label: col_labels){
        outputStream << label << "\t";
    }
}
执行该程序时,您将获得:

*FIELD_VALUE*
(FIELD_VALUE)
-- FIELD_VALUE --

我希望这些例子能让你在C++中对函数编程进行测试。

<代码>……函数编程技巧。是的,你可以!用C++ <代码> lambdas< /COD>和<代码> STD::函数< /Cord> .@ WESLY.MeSiga,请举例说明,我从您的解决方案中得到了一个解决方案。谢谢你的建议。:)很抱歉,但我不愿意将标题定义为数组,这仍然不够有序。我认为用字符串来定义对象更干净。无论如何,谢谢你的帮助,你得到了+1:)
void printHeaders(std::ofstream& outputStream){
    const std::vector<std::string> col_labels = {"col_label1", 
                                                "col_label2", 
                                                "col_label3"};
    for(auto& label: col_labels){
        outputStream << label << "\t";
    }
}
#include<fstream>
#include<functional>
#include<string>

std::string formatAsterix(const std::string& str){
    //bad design concat std::strings... just to show the idea
    return std::string("*") + str + std::string("*");  
} 

std::string formatParenthesis(const std::string& str){
    return std::string("(") + str + std::string(")"); 
} 

void printFormatted(std::ofstream& outputStream, /*Your output stream*/
                    const std::string str, /*your string*/
                    std::function<std::string(const std::string&)> formatter ) /*your formatter function*/
{
    outputStream << formatter(str) << std::endl;
}


int main(){
    std::ofstream outputStream; 
    outputStream.open("c:\\tmp\\out.txt");

    printFormatted(outputStream, "FIELD_VALUE", formatAsterix);
    printFormatted(outputStream, "FIELD_VALUE", formatParenthesis);

    // This last one uses a lamba expression
    printFormatted(outputStream, "FIELD_VALUE", 
    [&](const std::string str)
    { 
       return std::string("-- ") + str + std::string(" --");    
    });


    outputStream.close();
}
*FIELD_VALUE*
(FIELD_VALUE)
-- FIELD_VALUE --