2017-09-14 38 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也。