Matlab一個錯誤引發的血案:??? Error using ==> str2num Requires string or character array input

http://www.cnblogs.com/csulennon/p/4204258.html


Matlab總遇到一些神奇的問題,讓人摸不着頭腦。昨天編寫程序的時候遇到一個讓我十分火大的問題,也是自己的matlab基礎不好吧。

先描述一下問題,再GUI界面有個listbox,Tag屬性是’listbox1’,裏面是這樣的數據,我的目的是要把這些數據轉換成數值類型的矩陣:

QQ截圖20150105161932

list_string = get(handles.listbox1,'string') 
data=str2num((list_string));

使用上面兩行代碼進行轉換卻異常出錯了!看後臺的錯誤描述如下:

??? Error using ==> str2num 
Requires string or character array input.

Error in ==> wsy>pushbutton24_Callback at 654 
data=str2num((list_string));

Error in ==> gui_mainfcn at 75 
        feval(varargin{:});

Error in ==> wsy at 16 
    gui_mainfcn(gui_State, varargin{:});

??? Error while evaluating uicontrol Callback.

??? Error using ==> feval 
Undefined command/function 'Untitled_1_Callback'.

Error in ==> gui_mainfcn at 75 
        feval(varargin{:});

Error in ==> wsy at 16 
    gui_mainfcn(gui_State, varargin{:});

??? Error while evaluating uimenu Callback.

Matlab拋出的異常說明str2num函數使用錯誤,參數必須是字符數組(char array)或者是字符串(string)。在後臺看了下獲得的listbox裏面的數據如下:

list_string =

    ' 56      30      3.09       0' 
    ' 32      46      3.83      30' 
    ' 19      48      3.91      76' 
    ……(省略一大堆數據) 
    ' 31     301      9.79    6634' 
    ' 60     429     11.69    6935'

對呀!尼瑪難道這個不是符合要求的數據?不信我們在交互界面裏面做個試驗:

str=[' 56      30      3.09       0'; ' 32      46      3.83      30'; ' 60     429     11.69    6935']

str2num(str)

image

難道不應該是這樣子的嗎?好吧,可能不應該是數組吧,我又做了如下的實驗:

str={' 56      30      3.09       0'; ' 32      46      3.83      30'; ' 60     429     11.69    6935'}

str2num(str)

image

果然報了相同的錯誤!在baidu和論壇裏面各種查,基本上沒有什麼滿意的答案,後來只好求助於文檔:

首先來看看str2num函數的用法:

>> help str2num 
STR2NUM Convert string matrix to numeric array. 
    X = STR2NUM(S) converts a character array representation of a matrix of 
    numbers to a numeric matrix. For example, 
        
         S = ['1 2'         str2num(S) => [1 2;3 4] 
              '3 4'] 
  
    The numbers in the string matrix S should be ASCII character 
    representations of a numeric values.  Each number may contain digits, 
    a decimal point, a leading + or - sign, an 'e' or 'd' preceding a 
    power of 10 scale factor, and an 'i' or 'j' for a complex unit. 
  
    If the string S does not represent a valid number or matrix, 
    STR2NUM(S) returns the empty matrix.  [X,OK]=STR2NUM(S) will 
    return OK=0 if the conversion failed. 
  
    CAUTION: STR2NUM uses EVAL to convert the input argument, so side 
    effects can occur if the string contains calls to functions.  Use 
    STR2DOUBLE to avoid such side effects or when S contains a single 
    number.

str2num的功能是將字符串矩陣轉換成數值數組,字符串必須是ASCII碼錶中的可轉化成數值的字符,如果字符串數組不是一個有效的數字或者不能過程一個矩陣,str2num函數就會返回一個空的矩陣,[X,OK]=STR2NUM(S),如果轉換失敗OK=0.

注意:str2num使用的是eval函數來轉換輸入的參數,所以如果字符串裏面包含了函數的調用,就會產生副作用,推薦使用str2double來避免副作用(當待轉換字符串矩陣S包含單個數字的時候)。

 

相信很多朋友都是看了這一段文檔,從此走向一條不歸之路。首先我們從這段文檔描述中可以獲取至少三個有用的信息

①str2num作用的對象是‘string matrix’也就是我們的錯誤描述中的string or characher array.

②轉換失敗就會[X, OK] 中OK就會返回0,轉換成功就會返回1(實驗可得)。如下例子:

str=['1 2 3 4'; '5 6    ']

[X,OK]=str2num(str)

imageimage

③當待轉換字符數組是單個數字的時候推薦使用str2double進行轉換,避免副作用,如下例子:

Examples 
   str2double('123.45e7') 
   str2double('123 + 45i') 
   str2double('3.14159') 
   str2double('2.7i - 3.14') 
   str2double({'2.71' '3.1415'}) 
   str2double('1,200.34')

得到如下結果:

1.2345e+009 
1.2300e+002 +4.5000e+001i 
3.1416 
-3.1400 + 2.7000i 
2.7100    3.1415 
1.2003e+003

按照文檔的推薦,str2num適用與轉換單個數字。所以

image轉換就會失敗!

我們注意到上面的example中以這樣一個例子:str2double({'2.71' '3.1415'}),看一下文檔的描述:

>> help str2double 
STR2DOUBLE Convert string to double precision value. 
    X = STR2DOUBLE(S) converts the string S, which should be an 
    ASCII character representation of a real or complex scalar value, 
    to MATLAB's double representation.  The string may contain digits, 
    a comma (thousands separator), a decimal point, a leading + or - sign, 
    an 'e' preceding a power of 10 scale factor, and an 'i' for 
    a complex unit. 
  
    If the string S does not represent a valid scalar value, STR2DOUBLE(S) 
    returns NaN.(轉換失敗返回NaN) 
  
    X = STR2DOUBLE(C) converts the strings in the cell array of strings C 
    to double.  The matrix X returned will be the same size as C.  NaN will 
    be returned for any cell which is not a string representing a valid 
    scalar value. NaN will be returned for individual cells in C which are 
    cell arrays.

注意到我標出的紅色部分,‘the strings in the cell array ’也就是說str2double還可以轉換cell 類型的數據。

但是使用str2double轉換我們需要轉換的數據還是不行呀:

image

好吧是我讀文檔不認真,人家都說了是轉換單個數字,改成這樣就可以了:

image

但是現在的問題是我要轉換一行裏面由於多個數字的數據怎麼辦呢?

回到本文開頭的位置:你會發現str2num的轉換str只是一個‘[]’和一個‘{}’的區別就能轉換了,由此可以推測他們的數據類型是不一樣的,再結合str2double裏面的描述可以推測‘{}’代表的就是‘cell’數據類型。

爲了驗證他們的數據類型我們做如下實驗:

image

image

果然,他們的數據類型是不一樣的!並且cell array所佔的空間要大得多幾乎是兩倍char array的大小。

那好了,現在的任務明確了,只需要將‘cell’類型的數據轉換成數組類型就行了。

我們看一下文檔:

Create cell array Syntax

c = cell(n) 
c = cell(m,n) or c = cell([m n]) 
c = cell(m,n,p,...) or c = cell([m n p ...]) 
c = cell(size(A)) 
c = cell(javaobj)


Description

c = cell(n) creates an n-by-n cell array of empty matrices. An error message appears if n is not a scalar. 
c = cell(m,n) or c = cell([m,n]) creates an m-by-n cell array of empty matrices. Arguments m and n must be scalars. 
c = cell(m,n,p,...) or c = cell([m n p ...]) creates an m-by-n-by-p-... cell array of empty matrices. Arguments m, n, p,... must be scalars. 
c = cell(size(A)) creates a cell array the same size as A containing all empty matrices. 
c = cell(javaobj) converts a Java array or Java object javaobj into a MATLAB cell array. Elements of the resulting cell array will be of the MATLAB type (if any) closest to the Java array elements or Java object.

文檔中描述了Cell類型的創建方式,但是我要的是轉換方式呀。繼續搜索文檔:

image

貌似發現了目標:

image

重點來了,使用cellstr()函數可以使用character array(字符數組)創建一個cell array,使用char()可以轉換回來!

終於看到了光明,實驗一下:

image

現在可以成功轉換了!

 


發佈了6 篇原創文章 · 獲贊 7 · 訪問量 163萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章