【问题标题】:fprintf giving me a blank .txt file in MATLABfprintf 在 MATLAB 中给了我一个空白的 .txt 文件
【发布时间】:2016-01-12 03:06:17
【问题描述】:

我在 MATLAB 中有一个复杂的代码,可以导入并运行旧的 fortran 代码。

fortran 代码运行一个电解精炼过程并创建许多各种数据的输出文件,但它只执行一次。

我们的目标是让 MATLAB 多次运行该程序,并让它每次都改变元素浓度。

它可以很好地完成这些事情。基本上,它采用我们输出文件中的最后一行值(元素权重百分比)并使用这些值更新输入文件,以便下一次运行将从最后一次停止的地方开始。

fortran 代码在每次运行时都会覆盖输入和输出文件。当尝试多次运行而不必每次都复制文件并重命名时,这是一个问题。

MATLAB 代码执行此操作:

% Step 1: Reading the data from the output file "outblk1" line by line.
    clear tline;
    fid = fopen('outblk1');
    tline{1}=fgetl(fid);
    cont=1;
    while ischar(tline{cont})
        cont = cont+1;
        tline{cont}=fgetl(fid);
    end
    fclose(fid);
    % Step 2: Rewriting the data presented in the output file "outblk1" in
    % the file "outblk1_step"
    fid = fopen( sprintf( 'outblk1_%i.txt',step), 'w');
    for i = 1:(numel(tline)-1)
        if tline{i+1} ==-1
            fprintf(fid, '%s', tline{i});
            break
        else
            fprintf(fid, '%s\n', tline{i});
        end
    end
    fclose(fid);

这对输出文件非常有效。除了标题的第一行之外,所有内容都是数字。

程序完成后,而不是 出局1

我明白了 输出块1 outblk1.txt outblk2.txt 等等

我想对输入文件做同样的事情。一切完成后,我只能访问原始输入文件(如果我在运行程序之前保存副本)和最后一个输出文件完成后更新的最后一个输入文件。我想要每个更新的输入文件。所以我这样做了:

 % Reading the data from "inpref"
clear tline;
fid = fopen('inpref');
tline{1} =textscan(fid, '%s');
cont=1;
while ischar(tline{cont})
    cont = cont+1;
    tline{cont}=textscan(fid, '%s');
end
fclose(fid);
% Rewriting the data from "inpref" to "inpref_step"
fid = fopen( sprintf( 'inpref_%i.txt',step), 'w');
for i = 1:(numel(tline)-1)
    if tline{i+1} ==-1
        fprintf(fid, '%s', tline{i});
        break
    else
        fprintf(fid, '%s\n', tline{i});
    end
end
fclose(fid);

我想要的只是每个更新的输入文件的副本。

inpref1.txt inpref2.txt 等等

就像我得到的输出文件一样。

我最初尝试使用 fget1 与代码的输出版本相同,但它不起作用,因为输入文件中混合了数据和数字。

我也试过这样:

% Reading the data from "inpref"
clear tline;
fid = fopen('inpref');
input =textscan(fid, '%s');
cont=1;
fclose(fid);
% Rewriting the data from "inpref" to "inpref_step"
fid = fopen( sprintf( 'inpref_%i.txt',step), 'w');
fprintf(fid, '%s\n', input);
fclose(fid);

但我收到此错误:

Error using fprintf
Function is not defined for 'cell' inputs.

Error in save_step_data (line 17)
fprintf(fid, '%s\n', input);

我查找了有关 fprintf、fopen、tline、fget、copyfile、textscan 和许多其他从那里分支出来的东西的 MATLAB 帮助信息,但它们都引导我用数字做一些事情。您不会认为仅制作文件副本并对其进行排序会如此困难,这样您就不必在每个循环中停止并重命名它。

排序有效。我得到了 inpref1.txt,...,其余代码工作正常,这是 10 个文件中的一大块,执行一个包含 100 个或更多部分的 fortran 代码,一切都很好。 inpref 文件本身仍会使用新的浓度数据正确更新。

我唯一的问题是文件的 .txt 副本完全空白。

我的另一个选择是进入 matlab 代码,用新的浓度更新输入文件,并找到一种方法来制作一个新文件,其中只包含每次附加的浓度值。我还需要每次运行的总质量。这些实际上是整个输入文件中唯一改变的两件事。以质量百分比表示的盐浓度和盐的总质量。

就我个人而言,我认为每次运行时复制输入文件会更容易。

【问题讨论】:

  • 我觉得这个建议有点脏,但你能让 MATLAB 用!system 运行 shell 命令吗?对于 Windows,这类似于 system(['copy inpref inpref_',num2str(step),'.txt'])。通常的警告适用,不要使用!system,除非你知道他们要做什么。 (也许我误解了你要做什么)
  • !可能有风险,因为输入文件充满了!因为这相当于 % 在 MATLAB 中注释掉一些东西
  • 这段代码是另一个matlab文件调用的子程序的一部分。整个 MATLAB 代码基本上是一个运行旧 fortran 程序的脚本。它允许我们更改变量而无需通过 300 行输入文件。然后它在循环中运行 fortran 程序,无论我们告诉它多少次。 fortran 代码每次都会覆盖输出文件和输入文件,因此上面的代码在每一步都会复制输出文件。我希望输入文件也一样,所以如果第 50 步的输出显示有问题,我可以查看输入文件 50,看看是什么原因造成的。

标签: matlab


【解决方案1】:

如果我理解正确,您可以简单地使用copyfile 制作一个不同名称的副本,而不是加载和读出文件。如果输入文件被覆盖而不是在每一步更新,movefile 也可以正常工作,但如果 fortran 程序每次运行时都希望从迭代中找到inpref,那么你应该坚持使用copyfile

例如

fname = sprintf('outblk1_%i.txt',step);
copyfile('outblk1', fname);

【讨论】:

  • 太棒了!这样可行。我之前尝试过copyfile,但它没有按我的意图工作。它给我的只是一个包含 %i 的文件。我还通过将原始代码中的“w”更改为“w+”来使其工作,但我认为 copyfile 将比逐行方式花费更少的时间。谢谢!
猜你喜欢
  • 2016-10-11
  • 2012-11-16
  • 1970-01-01
  • 2021-10-08
  • 2016-08-07
  • 2020-04-03
  • 2022-06-15
  • 2014-04-02
  • 1970-01-01
相关资源
最近更新 更多