MATLAB:无法解析多个浮点值
MATLAB: Cannot parse multiple floating-point values
我有一个带有 UITable 的 GUI(内置 GUIDE)。我读入两个数值并通过一系列步骤将浮点值转换为字符串。我希望用户能够单击包含这两个值(现在为字符串)的 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
最终,我得到的结果是如果我有一个字符串 exactly 如下:“7.4250Hz - 32.502Hz”(或将 Hz 替换为 "s"),我的程序只会产生“7.4250”。仅此而已。我试过 textscan、sscanf 和 strread。每一个我都明确地将我的过滤器设置为浮点数 (%f)。对于 strread,我尝试将其设置为循环多次 (strread('string', %f, 2)
)。我不知道还能做什么、尝试或改变什么。
关于未来读者的以下答案: 从技术上讲,任何一个答案都是 "correct"(我试过了) .它们都适用于略有不同的情况。如果您有固定格式,Ben 的回答非常适合一步获得结果。我自己的答案是跨多个步骤分解一个字符串,以便在每个步骤中访问数据(对于执行多个操作很有用),同时仍然能够处理不同的格式。安德拉斯的回答对于一步完成它很有用,它可以立即提供结果,同时仍然能够处理不同的格式。
查看 sscanf
文档 here,如果您需要字符串中的一组浮点数,则需要指定格式。这是此页面中与您的页面类似的示例:
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')
Ben的回答是固定格式情况下的正确答案。但是,就我而言,我的格式发生了变化。因此,我提出的解决方案(经过测试和验证)是使用 strtok
到 "break-down" 将字符串分成两个单独的字符串,使其更易于管理和解析。下面的代码。想法?
% --- 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
受我自己关于在 sscanf
之前使用 regexp
的评论的启发,这是一个仅使用前者的解决方案:
str=regexp(data,'(?<dataStart>[\d\.]+)[^\d\.]+(?<dataEnd>[\d\.]+)','names');
之后 str
将字段 dataStart
和 dataEnd
作为字符串(所以你之后需要 num2str
)。请注意,这仅适用于简单的浮点数(当然 regexp
可能会进一步复杂化 ad nauseam 如果有必要的话。好处是它可以适应更棘手的输入字符串,例如上面将处理前两个数字之间的任何数字和种类的非数字(和非点)文本。缺点是 regexp
.
我有一个带有 UITable 的 GUI(内置 GUIDE)。我读入两个数值并通过一系列步骤将浮点值转换为字符串。我希望用户能够单击包含这两个值(现在为字符串)的 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
最终,我得到的结果是如果我有一个字符串 exactly 如下:“7.4250Hz - 32.502Hz”(或将 Hz 替换为 "s"),我的程序只会产生“7.4250”。仅此而已。我试过 textscan、sscanf 和 strread。每一个我都明确地将我的过滤器设置为浮点数 (%f)。对于 strread,我尝试将其设置为循环多次 (strread('string', %f, 2)
)。我不知道还能做什么、尝试或改变什么。
关于未来读者的以下答案: 从技术上讲,任何一个答案都是 "correct"(我试过了) .它们都适用于略有不同的情况。如果您有固定格式,Ben 的回答非常适合一步获得结果。我自己的答案是跨多个步骤分解一个字符串,以便在每个步骤中访问数据(对于执行多个操作很有用),同时仍然能够处理不同的格式。安德拉斯的回答对于一步完成它很有用,它可以立即提供结果,同时仍然能够处理不同的格式。
查看 sscanf
文档 here,如果您需要字符串中的一组浮点数,则需要指定格式。这是此页面中与您的页面类似的示例:
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')
Ben的回答是固定格式情况下的正确答案。但是,就我而言,我的格式发生了变化。因此,我提出的解决方案(经过测试和验证)是使用 strtok
到 "break-down" 将字符串分成两个单独的字符串,使其更易于管理和解析。下面的代码。想法?
% --- 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
受我自己关于在 sscanf
之前使用 regexp
的评论的启发,这是一个仅使用前者的解决方案:
str=regexp(data,'(?<dataStart>[\d\.]+)[^\d\.]+(?<dataEnd>[\d\.]+)','names');
之后 str
将字段 dataStart
和 dataEnd
作为字符串(所以你之后需要 num2str
)。请注意,这仅适用于简单的浮点数(当然 regexp
可能会进一步复杂化 ad nauseam 如果有必要的话。好处是它可以适应更棘手的输入字符串,例如上面将处理前两个数字之间的任何数字和种类的非数字(和非点)文本。缺点是 regexp
.