【问题标题】:Remove repeated code in function definition删除函数定义中的重复代码
【发布时间】:2022-11-08 05:24:08
【问题描述】:

这是我的第一个问题,所以我可能会错过“正确的结构”。

无论如何,我有一个头文件,有一个函数。此函数 (void readFile()) 在 cpp 文件中定义。在这个定义中,我有很多重复的代码。

如果它在 main 中,我只需声明一个新函数,在其中定义可重复的,然后每次调用该函数。但由于它位于非主 cpp 文件中,因此我在此过程中遇到问题。

基本上,我的函数所做的是逐个字符地读取文件,并根据文本将数据保存到不同的对象中。

我的代码如下所示:

source.open("bookings.txt", std::ios::in);
char c;
source.get(c); 
            while (c != '|'){
                CurrentID.push_back(c);
                source.get(c);
            }
object.setID(CurrentID)

此代码重复自身,仅替换“object.setID”行。我尝试声明函数“search(std::ifstream x, char y, std::string z);”有定义

void Search(std::ifstream x, char y, std::string z){
    x.get(y); // next after |
    while (y != '|'){
        z.push_back(y);
        x.get(y);
    }
} 

但是,如果我尝试在“void readFile()”定义中调用此函数,如下所示:

// First block as a repeatable

source.get(c); 
            while (c != '|'){
                CurrentID.push_back(c);
                source.get(c);
            }
object->setID(CurrentID)
CurrentID.clear();

// second block as a function, with repeatable code commented out

void Search(std::ifstream quelle, char c, std::string &CurrentID);

            /* source.get(c); 
            while (c != '|'){
                CurrentID.push_back(c);
                source.get(c);
            }*/
            object->setPrice(stof (CurrentID));
            CurrentID.clear();

它从第一个块中的“CurrentID.clear()”直接跳转到第二个块中的“object->setPrice”,忽略了 void Search 函数的存在。 有什么建议如何使函数工作,或者以其他方式删除重复的代码?

【问题讨论】:

    标签: c++ function c++11 repeat redundancy


    【解决方案1】:

    我不知道这是否能准确回答你的问题。如果没有,请发布您的整个代码,尤其是 readFile 函数。

    假设您想要一个 readFile 函数:

    • 解析输入流,然后
    • 填写object结构列表的字段ID(字符串)和价格(浮点数),
    • 流中的值由| 字符分隔,并且,
    • 对重复代码使用第二个函数readToken(即,从输入流中读取,直到找到分隔符并返回一个字符串)。

    下面的代码就是这样做的。注意:

    • 您将readFilereadToken 定义为单独的函数,并且
    • 两者都改变​​了输入流的状态。

    [Demo]

    #include <iostream>
    #include <sstream>
    #include <string>  // stof
    #include <vector>
    
    struct object {
        std::string id;
        float price;
    };
    
    std::string readToken(std::istringstream& iss) {
        std::string ret{};
        char c{};
        while (true) {
            iss >> c;
            if (not iss.eof() and c != '|') {
                ret.push_back(c);
            } else {
                return ret;
            }
        }
    }
    
    std::vector<object> readFile(std::istringstream& iss) {
        std::vector<object> ret{};
        while (not iss.eof()) {
            auto id = readToken(iss);
            auto price = std::stof(readToken(iss));
            ret.emplace_back(id, price);
        }
        return ret;
    }
    
    int main() {
        std::istringstream input{"ID1|25.5|ID2|3.14"};
        auto objects = readFile(input);
        for (const auto& o : objects) {
            std::cout << o.id << ", " << o.price << "
    ";
        }
    }
    
    
    // Outputs:
    //
    //   ID1, 25.5
    //   ID2, 3.14
    

    更简单的方法是让std::getline 读取令牌:

    [Demo]

    std::vector<object> readFile(std::istringstream& iss) {
        std::vector<object> ret{};
        while (not iss.eof()) {
            std::string id{};
            std::getline(iss, id, '|');
    
            std::string price_str{};
            std::getline(iss, price_str, '|');
            auto price = std::stof(price_str);
    
            ret.emplace_back(id, price);
        }
        return ret;
    }
    

    【讨论】:

    • 嘿,感谢您的快速回复!虽然这不是我需要的确切答案,但它帮助我获得了新的视角。首先,由于我在main之外,我犯了一个致命的错误,这使我的程序跳过了这个函数——我在其他定义的定义中使用了关键字“void”,我想这是不允许的。无论如何,在我将函数调用为“Search (source, c, CurrentID);”的行重新制作之后,它实际上开始工作了。 (我还需要在函数本身中为 ifstream 添加一个引用:“void Search (std::ifstream& x, char y, std::string &z)”
    • 我很高兴它有帮助。 1)对于未来的问题,我建议您发布尽可能多的代码(最好是一个示例,以及指向在线站点的链接,例如godbolt,其中会重现错误),因为这有助于理解问题并寻找解决方案。 2) 是的,非常重要,将流作为非常量引用传递当您将一些工作委派给其他代码时。
    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 2018-08-07
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    相关资源
    最近更新 更多