使用C ++更改Fortran输入文件中的变量

时间:2012-07-30 17:54:11

标签: c++ loops fortran

我希望有人可以给我建议,以便从C ++应用程序轻松更改Fortran输入文件中各种变量的值。

我有一个用Fortran编写的模型,但我正在编写一个C ++应用程序来在循环中执行模型,但是在每个模型执行后更改模型参数的值。

任何建议都将不胜感激。

谢谢!

    .Pnd file Subbasin: 1 7/26/2012 12:00:00 AM ArcSWAT 2009.93.7
Pond inputs:
           0.000    | PND_FR : Fraction of subbasin area that drains into ponds. The value for PND_FR should be between 0.0 and 1.0. If PND_FR = 1.0, the pond is at the outlet of the subbasin on the main channel
           0.000    | PND_PSA: Surface area of ponds when filled to principal spillway [ha]
           0.000    | PND_PVOL: Volume of water stored in ponds when filled to the principal spillway [104 m3]
           0.000    | PND_ESA: Surface area of ponds when filled to emergency spillway [ha]
           0.000    | PND_EVOL: Volume of water stored in ponds when filled to the emergency spillway [104 m3]
           0.000    | PND_VOL: Initial volume of water in ponds [104 m3]
           0.000    | PND_SED: Initial sediment concentration in pond water [mg/l]
           0.000    | PND_NSED: Normal sediment concentration in pond water [mg/l]
           0.000    | PND_K: Hydraulic conductivity through bottom of ponds [mm/hr].
               0    | IFLOD1: Beginning month of non-flood season
               0    | IFLOD2: Ending month of non-flood season
           0.000    | NDTARG: Number of days needed to reach target storage from current pond storage
          10.000    | PSETLP1: Phosphorus settling rate in pond for months IPND1 through IPND2 [m/year]
          10.000    | PSETLP2: Phosphorus settling rate in pond for months other than IPND1-IPND2 [m/year]
           5.500    | NSETLP1: Initial dissolved oxygen concentration in the reach [mg O2/l]
           5.500    | NSETLP2: Initial dissolved oxygen concentration in the reach [mg O2/l]
           1.000    | CHLAP: Chlorophyll a production coefficient for ponds [ ] 
           1.000    | SECCIP: Water clarity coefficient for ponds [m]
           0.000    | PND_NO3: Initial concentration of NO3-N in pond [mg N/l]
           0.000    | PND_SOLP: Initial concentration of soluble P in pond [mg P/L]
           0.000    | PND_ORGN: Initial concentration of organic N in pond [mg N/l]
           0.000    | PND_ORGP: Initial concentration of organic P in pond [mg P/l]
           5.000    | PND_D50: Median particle diameter of sediment [um]
               1    | IPND1: Beginning month of mid-year nutrient settling "season"
               1    | IPND2: Ending month of mid-year nutrient settling "season"
Wetland inputs:
           0.000    | WET_FR : Fraction of subbasin area that drains into wetlands
           0.000    | WET_NSA: Surface area of wetlands at normal water level [ha]
           0.000    | WET_NVOL: Volume of water stored in wetlands when filled to normal water level [104 m3] 
           0.000    | WET_MXSA: Surface area of wetlands at maximum water level [ha]
           0.000    | WET_MXVOL: Volume of water stored in wetlands when filled to maximum water level [104 m3]
           0.000    | WET_VOL: Initial volume of water in wetlands [104 m3]
           0.000    | WET_SED: Initial sediment concentration in wetland water [mg/l]
           0.000    | WET_NSED: Normal sediment concentration in wetland water [mg/l]
           0.000    | WET_K: Hydraulic conductivity of bottom of wetlands [mm/hr]
           0.000    | PSETLW1: Phosphorus settling rate in wetland for months IPND1 through IPND2 [m/year]
           0.000    | PSETLW2: Phosphorus settling rate in wetlands for months other than IPND1-IPND2 [m/year]
           0.000    | NSETLW1: Nitrogen settling rate in wetlands for months IPND1 through IPND2 [m/year]
           0.000    | NSETLW2: Nitrogen settling rate in wetlands for months other than IPND1-IPND2 [m/year]
           0.000    | CHLAW: Chlorophyll a production coefficient for wetlands [ ]
           0.000    | SECCIW: Water clarity coefficient for wetlands [m]
           0.000    | WET_NO3: Initial concentration of NO3-N in wetland [mg N/l]
           0.000    | WET_SOLP: Initial concentration of soluble P in wetland [mg P/l]
           0.000    | WET_ORGN: Initial concentration of organic N in wetland [mg N/l]
           0.000    | WET_ORGP: Initial concentration of organic P in wetland [mg P/l]
           0.000    | PNDEVCOEFF: Actual pond evaporation is equal to the potential evaporation times the pond evaporation coefficient
           0.000    | WETEVCOEFF: Actual wetland evaporation is equal to the potential evaporation times the wetland evaporation coefficient.

5 个答案:

答案 0 :(得分:1)

查看Fortran的名单 I / O,它可能适合您的目的。此功能的IBM XL Fortran文档为here。请务必查阅您自己的编译器的文档,每个文档在标准上都有一些奇怪的变化(或者标准可能不够严格)。

答案 1 :(得分:0)

我不是FORTRAN的专家,但我想我会考虑为每个需要更改的参数使用命令行参数。但是,如果您使用FORTRAN 2003,这是唯一可行的。我认为FORTRAN 95仍然是最常用的FORTRAN标准之一,但我不确定。如果您的FORTRAN实现支持命令行参数,请查看此站点是否可以帮助您弄清楚如何使用它们:http://fortranwiki.org/fortran/show/Command-line+arguments 否则,您可以从文本文件中读取FORTRAN程序的值。如果你想变得非常讨厌,你可以让你的C ++程序实际改变FORTRAN源文件,并在每次需要运行时重新编译它。如果你这样做,那么先备份它。祝你好运。

答案 2 :(得分:0)

据我了解你的问题,你只需要在C ++中进行一些文本编辑。 我想最简单的方法是在C ++代码中包含所有参数,并让代码为每次运行编写完整的文本文件。 如果您不想这样做,我建议使用一些模板工具箱,可能是cpptemplateteng,尽管可能有更多的模板引擎可供C ++使用,可能适合您的用例。

答案 3 :(得分:0)

我的工具就像在一个20字节的ASCII字段中有一个数字,一个'|'符号,以及以':'结尾的变量名称。线条长度可变。所以像这样:

// ./bin/bin/g++ -o hackpond hackpond.cpp

#include <fstream>
#include <string>
#include <cstddef>
#include <sstream>
#include <iomanip>

int
main()
{
    std::string variable_you_want = "PND_SOLP";
    std::string line;
    std::fstream pond("test.pnd");
    std::getline(pond, line);
    while (! pond.eof())
    {
    std::string value, variable;
    std::size_t loc = pond.tellg();
    std::getline(pond, line);
        if (line == "Pond inputs:")
            continue;
        else if (line == "Wetland inputs:")
            continue;
        std::ostringstream hack();
        value = line.substr(0, 20);
        std::size_t colon = line.find(':', 20);
        if (colon == std::string::npos)
            continue;
        variable = line.substr(22, colon - 22);
    if (variable == variable_you_want)
    {
            double new_value = 666.66;
            pond.seekp(loc);
            std::ostringstream thing;
            thing << std::setw(20) << new_value;
            pond.write(thing.str().c_str(), thing.str().length());
    }
        if (pond.eof())
            break;
    }
}

基本思路是1.注意要更改的行的起始位置(tellg),2。创建包含新值的20个字符的字符串,3。转到保存的起始位置该行(seekp)并写下新的块。

答案 4 :(得分:0)

我知道你要求使用C ++,但我的代码与我的代码非常相似,我使用的是shell脚本。

我使用sed s/var_name/value <template >input_file更改模板中var_name的出现次数。我的文件格式设置为简单,但sed是一个超级灵活的工具,我相信它可以做你要求的。有一个教程here

通过这个设置,我编写了一个脚本来循环遍历这些sed命令和应用程序调用。这就像一个魅力。此外,学习一点脚本将帮助您处理所有其他任务,例如对从所有不同运行中生成的数据进行排序。