1

我有一个带有 UITable(内置 GUIDE)的 GUI。我读入两个数值并通过一系列步骤将浮点值转换为字符串。我希望用户能够单击 UITable 中包含两个值(现在作为字符串)的特定单元格,并将这些值作为浮点值读回。无论出于何种原因,我只能让我的代码读取第一个浮点值。我的代码(按顺序)如下。

步骤1:访问数据并转换为字符串并将字符串放在相应的列中。

function fillAnnotRangeInfo(obj, selectedAxes)

    selectedAxesTag = selectedAxes.Tag; 
    rawAxesTag = obj.rawDataDisplayAxes.Tag; 
    psdAxesTag = obj.psdDataDisplayAxes.Tag; 

    % Depending on which axes the user clicks on, the units will either be Hz or s 
    if strcmp(selectedAxesTag, rawAxesTag)
        dataRange = strcat(num2str(obj.t1), {'s'}, {' - '}, num2str(obj.t2), {'s'});
    elseif strcmp(selectedAxesTag, psdAxesTag)
        dataRange = strcat(num2str(obj.t1), {'Hz'}, {' - '}, num2str(obj.t2), {'Hz'}); 
    end 

    obj.nextRow.AnnotRange = dataRange; 

end  

第 2 步:确定用户是否点击了正确的单元格并尝试读取两个浮点值。

% --- Executes when selected cell(s) is changed in existingAnnotationsTable.
function existingAnnotationsTable_CellSelectionCallback(hObject, eventdata, handles)
% hObject    handle to existingAnnotationsTable (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
%   Indices: row and column indices of the cell(s) currently selecteds
% handles    structure with handles and user data (see GUIDATA)

% AE = handles.UserData; 

Indices = eventdata.Indices; 

% Determine if column is column of interest 
if Indices(2) == 4
    rangeData = handles.existingAnnotationsTable.Data;
    rangeData = rangeData{Indices(1), Indices(2)}; 
    annoRange = sscanf(rangeData, '%f')
else

end


return

最终,我得到的结果是,如果我有一个完全如下的字符串:“7.4250Hz - 32.502Hz”(或用“s”替换Hz),我的程序只会产生“7.4250”。不多不少。我试过 textscan、sscanf 和 strread。每一个我都明确地将我的过滤器设置为浮点 (%f)。使用 strread 我尝试将其设置为多次循环(strread('string', %f, 2))。我不知道还能做什么或尝试或改变。

关于未来读者的以下答案:从技术上讲,任何一个答案都是“正确的”(我试过了)。它们都适用于稍微不同的情况。如果您有固定的格式,Ben 的答案很适合一步获得结果。我自己的答案可以跨多个步骤分解字符串,从而在每个步骤中都可以访问数据(对于执行多个操作很有用),同时仍然能够处理不同的格式。安德拉斯的回答对于一步完成它很有用,可以立即提供结果,同时仍然能够处理不同的格式。

4

3 回答 3

2

看看这里sscanf的文档,如果你想要一个字符串中的一组浮点数,你需要指定格式。这是此页面中与您的示例类似的示例:

tempString = '78°F 72°F 64°F 66°F 49°F';

degrees = char(176);
tempNumeric = sscanf(tempString, ['%d' degrees 'F'])'
tempNumeric =
    78    72    64    66    49

在您的具体情况下,您可以尝试:

val = sscanf(rangedata,'%fHz - %fHz')
于 2015-08-13T22:08:13.387 回答
1

本的答案是固定格式情况下的正确答案。但是,就我而言,我的格式发生了变化。因此,我提出的解决方案(经过测试和验证)是用来strtok将字符串“分解”为两个单独的字符串,使其更易于管理和解析。代码如下。想法?

% --- Executes when selected cell(s) is changed in existingAnnotationsTable.
function existingAnnotationsTable_CellSelectionCallback(hObject, eventdata, handles)
% hObject    handle to existingAnnotationsTable (see GCBO)
% eventdata  structure with the following fields (see MATLAB.UI.CONTROL.TABLE)
%   Indices: row and column indices of the cell(s) currently selecteds
% handles    structure with handles and user data (see GUIDATA)

% AE = handles.UserData; 

Indices = eventdata.Indices; 

% Determine if column is column of interest 
if Indices(2) == 4
    rangeData = handles.existingAnnotationsTable.Data;
    rangeData = rangeData{Indices(1), Indices(2)}; 

    [dataStart, dataRemain] = strtok(rangeData); 
    % In this case, since there will be just a '-' as the token...
    % ...we don't care about the token and only save the remainder. 
    [~, dataEnd] = strtok(dataRemain); 
    dataStart = sscanf(dataStart, '%f') 
    dataEnd = sscanf(dataEnd, '%f')

else

end
于 2015-08-13T22:40:12.743 回答
1

受我自己关于使用regexpbefore的评论的启发sscanf,这是一个仅使用前者的解决方案:

str=regexp(data,'(?<dataStart>[\d\.]+)[^\d\.]+(?<dataEnd>[\d\.]+)','names');

之后str将有字段dataStartdataEnd字符串(所以你num2str以后需要)。请注意,这仅适用于简单的浮点数(但当然,如果必要的话,regexp可能会更加复杂且令人作呕)。好处是它可以适应更棘手的输入字符串,例如上面将处理前两个数字之间的任何数字和类型的非数字(和非点)文本。缺点是regexp

于 2015-08-13T23:05:40.543 回答