【问题标题】:Matlab execute for loop again untill first statements endMatlab再次执行for循环,直到第一条语句结束
【发布时间】:2014-06-21 06:04:40
【问题描述】:

我正在从 Matlab 编写一个外部文件。我想将几种类型的 fprintf 语句放在同一个 for 循环中,写入同一个文件。但是,我希望将每种类型的 fprintf 语句产生的行组合在输出文件中。也就是说,迭代第一个 fprintf 语句产生的所有行都应该在迭代第二个 fprintf 语句产生的所有行之前。

这可以通过为每个 fprintf 语句设置一个单独的 for 循环来轻松实现,但应该有一种更优雅的方法来做到这一点,尤其是当我有多种类型的 fprintf 语句时。

 for ii=1:length(fieldnames(isom))
    clear cau cou
    cau=1; cou=1
    for kk=1:size(isom.(['m' num2str(ii)]),1)
        fprintf(fileID,'MPTEMP,,%d,%d,%f\n',size(isom.(['m' num2str(ii)]),1),cau,isom.(['m' num2str(ii)])(kk,1));
        cau=cau+1;
        %Wait until first fprintf ends then
        fprintf(fileID,'MPDATA,,%d,NUXY,%d,%d,%f\n',size(isom.(['m' num2str(ii)]),1),ii,cou,Info{ft(1,1),3});
        cou=cou+1;
    end
end

【问题讨论】:

  • 所以让我试着通过提问来了解您的情况 - 输出文件将包含类似 MPTEMP 的文本,用于 kk=1,然后用于 kk=2,直到内部 for loop with kk 结束并然后MPDATA for kk=1,2 依此类推,直到 kk 最终进入内部循环。但随后,它回到外循环并重新开始并再次创建MPTEMPMPDATA。所以这是我的问题 - 你想在 iikk 定义的两个循环中对 MPTEMP 进行分组,还是只在内部 kk 循环中分组?

标签: matlab for-loop conditional-statements


【解决方案1】:

想一想写入文件的作用:它按顺序(通常)将字节从内存复制到存储介质。您要求的是执行以下操作(我假设第一个 fprintf 在后续调用中写入 aaa,bbb,ccc,第二个写入 AAA,BBB,CCC)。

在每次迭代之后,您希望文件内容成为本系列的下一行:

aaaAAA              - after first pass
aaabbbAAABBB        - after second pass
aaabbbcccAAABBBCCC  - after third pass

现在,如果您确切知道第一个语句的所有著作的总长度,您可以这样做

aaa      AAA
aaabbb   AAABBB
aaabbbcccAAABBBCCC

使用“随机访问”文件

“有时”可能没问题。但是我认为在内存中创建这些块并最终将它们写出来更有意义。你可以用sprintf而不是fprintf来做到这一点:

s1 = '';
s2 = '';
for ii=1:5
  s1 = [s1 sprintf('format etc', data, data)];
  s2 = [s2 sprintf('other format', otherData)];
end

最后你按顺序写出来:

fprintf(fileID, '%s%s', s1, s2);

不理想,因为您可能会冒着增加字符串的风险,这可能会很慢(如果对于分配的空间来说太大,则必须移动整个字符串;随着字符串变大,这会逐渐变慢。您可以如果您知道字符串有多大,请预先分配字符串,但这会增加很多复杂性)。

真的 - 一系列 for 循环一次对一种类型的数据执行所有操作,以便按照您想要的顺序生成输出,这不是一个糟糕的计划。

另一种解决方案 - 绕过一些内存分配问题:使用 sprintf 将值放入 2D 元胞数组 - 完成后,将元胞数组的转置打印到文件中。

storage = cell(3,2);
for ii=1:3
  storage{ii,1}=sprintf('%d \n',ii);
  storage{ii,2}=sprintf('%.2f\n', ii);
end

% now write the resulting strings in the order you want them:
for ii = 1:2
  for jj = 1:3
    fprintf(1, '%s', storage{jj,ii});
  end
end

% but you don't even need these loops:
fprintf(1, 'and now all at once:...\n');
fprintf(1, '%s', [storage{:}])

这个输出就是你要找的:

1 
2 
3 
1.00
2.00
3.00
and now all at once:...
1 
2 
3 
1.00
2.00
3.00

如您所见,尽管我们将交替的 %d%.2f 数字写入元胞数组,但在最终输出中,它们会按照您的需要进行分组。通过像我对元胞数组所做的那样选择索引的顺序,打印整个内容就变成了一行(而不是第二组嵌套循环)。

【讨论】:

  • 我猜我们都聚集到sprintf! +1
【解决方案2】:

您可以使用sprintf 代替fprintf,并将所有数据存储到一个元胞数组中,并在最后写入文件。此外,这样可以避免为每个fprintf 编写多个for 循环。确保输出格式是您正在寻找的,正如我在您的问题下的评论中所问的那样。

代码

M = numel(fieldnames(isom));%%// numel is preferred over length
N = size(isom.(['m' num2str(length(fieldnames(isom)))]),1);

data = cell(M,N,2); %%// 2 is the no. of sprintfs used

for ii=1:M
    clear cau cou
    cau=1; cou=1;

    %%// Add all your fprintf statements as sprintf under this one FOR
    %%// loop, like data(ii,kk,3), data(ii,kk,4) etc.
    for kk=1:N
        data(ii,kk,1) = {sprintf('MPTEMP,,%d,%d,%f\n',size(isom.(['m' num2str(ii)]),1),cau,isom.(['m' num2str(ii)])(kk,1))};
        data(ii,kk,2) = {sprintf('MPDATA,,%d,NUXY,%d,%d,%f\n',size(isom.(['m' num2str(ii)]),1),ii,cou,Info{ft(1,1),3})};
        cau=cau+1;
        cou=cou+1; %%// Maybe you can avoid using both cau and cou by using kk instead
    end
end

data = data(:);
for k = 1:size(data,1)
    fprintf(fileID,'%s',data{k,:});
end

fclose(fileID);

【讨论】:

  • 完全有道理! :)
【解决方案3】:

很难理解你的问题,但是如果我理解你想用一个 print 语句对所有迭代进行循环,然后用另一个 print 语句对所有迭代进行循环,你为什么不只是执行循环两次?

for ii=1:length(fieldnames(isom))
    clear cau cou
    cau=1; cou=1
    for kk=1:size(isom.(['m' num2str(ii)]),1)
        fprintf(fileID,'MPTEMP,,%d,%d,%f\n',size(isom.(['m' num2str(ii)]),1),cau,isom.(['m' num2str(ii)])(kk,1));
        cau=cau+1;
    end
    for kk=1:size(isom.(['m' num2str(ii)]),1)    
        fprintf(fileID,'MPDATA,,%d,NUXY,%d,%d,%f\n',size(isom.(['m' num2str(ii)]),1),ii,cou,Info{ft(1,1),3});
        cou=cou+1;
    end
end

【讨论】:

  • 其实我也有过这样的想法,但我想知道是否存在不同的解决方案;问题是我有几个 fprintf 项目,我必须为每个项目编写 for 语句。
  • 如何将它们打印到不同的文件中,然后在最后连接文件?
  • 这实际上听起来不错,我会试一试,顺便说一句,现在我认为您理解我在问题中的观点,您可以编辑它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多