为什么Matlab textscan函数无法读取+ 22.24作为浮点数?

Why can't the matlab textscan function read + 22.24 as a float?

我目前在matlab函数textscan上遇到问题。
我得到了一个数据文件,看起来像这样:

1
     1,2018/08/14 17:06:15,  0,+ 22.24,+ 22.46,+ 18.18,+0.0000,+0.0005,LLLLLLLLLL,LLLLLLLLLL,LLLL

或有时当传感器无法正常工作时,它看起来像这样:

1
   1,2018/07/11 17:02:53,  0,+ 23.88,+ 24.78,+ 23.65,+++++++,+ 23.94,+ 23.01,+ 24.33,LLLLLLLLLL,LLLLLLLLLL,LLLL

由于数据因文件而异,所以我要从标题行创建匹配的formatSpec。
在第一种情况下,它看起来像

1
2
formatSpec = '%*u %s %*u%f%f%f%f%f%*[^\
]'

在第二种情况下

1
2
formatSpec = '%*u %s %*u%f%f%f%f%f%f%f%*[^\
]'

我正在像这样使用texscan函数:

1
textscan(fileID, formatSpec_data, data_rows, 'Delimiter', ',', 'TreatAsEmpty', {'+++++++'},'EmptyValue', NaN, 'ReturnOnError', 0 );

但消息不断向我抛出错误

1
2
3
4
5
6
7
Error using textscan
Mismatch between file and format character vector.
Trouble reading 'Numeric' field from file (row number 1, field number 4) ==> + 23.88,+ 24.78,+ 23.65,+++++++,+ 23.94,+ 23.01,+ 24.33,LLLLLLLLLL,LLLLLLLLLL,LLLL\


Error in data_logger (line 31)
dataArray = textscan(fileID, formatSpec_data, data_rows, 'Delimiter', delimiter, 'HeaderLines' ,startRow, 'TreatAsEmpty', {'+++++++'},'EmptyValue', NaN, 'ReturnOnError', 0 );

当我停用'returnOnError'时,textscan仅读取第一行,除了日期/时间字符串之外,所有内容均为空。我也尝试使用不带TreatAsEmpty和/或EmptyValue的textscan,但得到的结果相同。
我真的不明白为什么textscan在阅读时遇到问题,+ 22.24作为浮点数。
当我指定formatSpec以字符串形式读取所有数据时,它可以工作,但是之后我必须使用str2num,而我实际上并不想这样做。

我非常感谢您提供的所有帮助,并希望了解这一行为。


简短的答案:Matlab不喜欢这些字段中+和数字之间的空格。 我认为最简单的解决方案可能就是通过将其称为空白来告诉Matlab忽略+。 调用textscan时添加参数'WhiteSpace','+',如下所示:

1
textscan(fileID, formatSpec_data, data_rows, 'Delimiter', ',', 'EmptyValue', NaN, 'ReturnOnError', 0 , 'WhiteSpace', '+');

请注意,我还删除了'TreatAsEmpty'参数,因为一旦您将所有+都视为空格,则无论如何它都是空的。

另一种选择是预解析文件并删除+和数字之间的空格。 您可以使用fileread读取文件,使用strrep或regexprep进行替换,然后对结果运行textscan。

1
2
3
datain = fileread('mydatafile.csv')
datain = strrep(datain,'+ ','+');
textscan(datain, formatSpec_data, data_rows, 'Delimiter', ',', 'TreatAsEmpty', {'+++++++'},'EmptyValue', NaN, 'ReturnOnError', 0 );

最后,如果您陷入绝对必须阅读为文本然后转换为数值的地方,请尝试使用Matlab文件交换上的str2doubleq。 它比str2double或str2num快得多。