2017-09-14 43 views
4

我想运行几行代码,但我不确定是否有任何行会抛出错误。如果发生错误,我希望脚本忽略该行并继续。顺序尝试捕捉结束块的matlab

一个选择是有一个try-catch-end块,它跳过可能会引发错误的代码块。但是,只要发生错误,try-statement中的错误之后的其余代码就不会执行。

TL; TR:除了在下面的示例代码中为每条单独的行编写try-catch-end块之外,还有其他选择吗?

示例代码:

try 
    disp('1st line'); 
    disp('2nd line'); 
    PRODUCE_ERROR; %throws an error, variable/function does not exist 
    disp('3rd line'); %%%%% 
    disp('4th line'); % these lines I would like to keep executing 
    disp('5th line'); %%%%% 
catch 
    disp('something unexpected happened'); 
end 

输出:

1st line 
2nd line 
something unexpected happened 

输出将是优选的:

1st line 
2nd line 
something unexpected happened 
3rd line 
4th line 
5th line 

相关:Why should I not wrap every block in "try"-"catch"?

+0

我可以想出解决这个问题的递归方法,但这可能不是最优雅的方式...... – user2305193

+0

您可以通过不重新抛出错误来继续其余代码。你可以发布[mcve]吗? – beaker

+0

即使您不重新抛出错误,“catch”分支的其余部分也会被跳过。例如见'clear,a = 1; c = 3;尝试,显示(a),显示(b),显示(c),结束' –

回答

4

一种选择是把函数中的每段代码并遍历function handlescell array。下面是与anonymous functions列表的例子:

fcnList = {@() disp('1'); ... 
      @() disp('2'); ... 
      @() error(); ... % Third function throws an error 
      @() disp('4')}; 

for fcnIndex = 1:numel(fcnList) 
    try 
    fcnList{fcnIndex}(); % Evaluate each function 
    catch 
    fprintf('Error with function %d.\n', fcnIndex); % Display when an error happens 
    end 
end 

,这里是此产生,显示出功能甚至一个后仍评估输出抛出Error:

1 
2 
Error with function 3. 
4 

上面的例子工程的情况下当你有个别行的代码要连续评估,但不能将多行转换成匿名函数。在这种情况下,如果他们必须访问较大的工作空间中的变量或local functions(如果它们可以独立运行),那么我将使用nested functions。下面是与嵌套函数的例子:

function fcn1 
    b = a+1;  % Increments a 
    fprintf('%d\n', b); 
end 
function fcn2 
    error();  % Errors 
end 
function fcn3 
    b = a.^2; % Squares a 
    fprintf('%d\n', b); 
end 

a = 2; 
fcnList = {@fcn1 @fcn2 @fcn3}; 

for fcnIndex = 1:numel(fcnList) 
    try 
    fcnList{fcnIndex}(); 
    catch 
    fprintf('Error with function %d.\n', fcnIndex); 
    end 
end 

和输出:

3 
Error with function 2. 
4 
+0

是否存在一种快速和肮脏的方式,您会建议将代码行转换为匿名列表功能? – user2305193

+0

@ user2305193:我又增加了一个例子。希望有所帮助。 – gnovice

+0

我的意思是更简单,就像在搜索和替换这些代码行一样。但我想这是更多的事情,你会做一个简单的记事本替换命令(至少在Windows中)。带有多行代码的例子对我来说没有意义,因为(据我所知),每个命令行都需要大约相同数量的代码来编写try-catch-end语句。 – user2305193

1

更简单的方法包括读取由行脚本文件中的行和评估反过来每一行。这假设您要运行的脚本不包含任何多行语句(例​​如forend在不同的行上,或者使用...将语句分解为多行)。这是一个很强的限制,因为它很常见于例如使用多行文本初始化矩阵。

这是函数:

function execute_script(fname) 
fid = fopen(fname,'rt'); 
n = 0; 
while ~feof(fid) 
    cmd = fgetl(fid); 
    n = n+1; 
    if ~isempty(cmd) 
     try 
     evalin('caller',cmd); 
     catch exception 
     disp(['Error occurred executing line number ',num2str(n),': ',exception.message]); 
     end 
    end 
end 

它确实完全按照我如上所述:它在一个行读取,然后使用evalin来评估呼叫者的工作区线。创建的任何变量都在调用者的工作区中创建。任何使用的变量都来自调用者的工作区。

例如,我创建文件testscript.m具有以下内容:

A = 1; 
B = 2+C; % This line needs a variable not defined in the script! 
D = 5; 

接着,在MATLAB命令提示:

>> execute_script('testscript.m') 
Error occurred executing line number 2: Undefined function or variable 'C'. 
>> whos 
    Name  Size   Bytes Class   Attributes 

    A   1x1     8 double     
    D   1x1     8 double     

可变AD创建。如果我定义C

>> C=0; 
>> execute_script('testscript.m') 
>> whos 
    Name  Size   Bytes Class   Attributes 

    A   1x1     8 double     
    B   1x1     8 double     
    C   1x1     8 double     
    D   1x1     8 double     

随着定义的变量C,脚本运行而不会出现错误,并限定B也。