2016-11-25 150 views
0

我对matlab很新颖。我一直在阅读文档,但可以找出为什么matlab不能正确读取文件中的字符串。我想要做的是从文件中读取混合的数据类型。一些示例数据是:从文件读取混合数据的matlab

t a e incl lasc aper meanan truean rupnode rdnnode name 
0.000000 1.2712052487 0.8899021688 22.2458 265.2511471042 322.1539251184 -13.6281352271 -130.986 0.155342 0.889756 phaet_000018 
0.000000 1.2712052478 0.8899021575 22.2458 265.2511428392 322.1539270642 -13.6281369694 -130.986 0.155342 0.889756 phaet_000044 
0.000000 1.2712052496 0.8899021868 22.2458 265.2511587897 322.1539149438 -13.6281365049 -130.986 0.155342 0.889755 phaet_000006 

第一行是标题。所以这是我迄今所做的:

fid = fopen('data.dat'); 
header = fgetl(fid); # I read the header 

Now I read the data: 

data = fscanf(fid,'%f %f %f %f %f %f %f %f %f %f %s',[11 inf]); 
data1 = data'; 
fclose(fid); 

我现在可以作为访问的第一要素:

data1(1,1) 

然而,当我这样做:

data(1,11) 

,而不是phaet_000018我得到一个数字(112)。任何想法我做错了什么?

+0

把矩阵负荷的打印在MATLAB – 16per9

+0

我很抱歉,我没”没有那个。你能否详细说明一下? – user3578925

回答

0

您的代码有几个问题。

首先,您的sizeA输入到fscanf是倒退。带有向量输入的sizeA定义为:

最多可以读取m*n数值或字符字段。 n可以是Inf,但是m不可以。输出Am -by-n,按列顺序填充。

所以你问fscanf给你11行和任何数量的列。你不能有一个Inf行规范,所以你想要完全删除第三个输入,然后你想要删除你的数据。

例如:

fid = fopen('data.dat'); 
header = fgetl(fid); 

data = fscanf(fid,'%f %f %f %f %f %f %f %f %f %f %s'); 
fclose(fid); 

% We just happen to know this explicitly, not knowledge to generally assume 
ncols = 22; 

% Reshape and transpose 
data = reshape(data, ncols, []).'; 

给了我们一个3 x 22data阵列,这是有点儿八九不离十我们想要的。


那么额外的列从哪里来?对于%s字段,fscanf会读取该字符串,直至遇到空白为止。因为fscanf的输出是数字数组,所以它必须将此字符串转换为数字值,以便将每个字符转换为其数字等效(double(letter))并将其输出到矩阵中。

使用我们上面data矩阵作为一个例子,我们有:

>> char(data(1, 11:end)) 

ans = 

phaet_000018 

考虑到这一点,你最初的代码只发生在工作,因为您的所有字符串的长度相同。如果我们改变一个或多个字符串的长度,这个数据导入将失败:

Error using reshape 
Product of known dimensions, 22, not divisible into total number of elements, 65. 

Error in testcode (line 11) 
data = reshape(data, ncols, []).'; 

所以,我们能做些什么呢?如果您需要从数据这个字符串我会建议您尝试textscan

fid = fopen('data.dat'); 
header = fgetl(fid); 

data = textscan(fid, '%f %f %f %f %f %f %f %f %f %f %s'); 
fclose(fid); 

这将读取你的数据转换为1x11 cell array,其中每列对应的列在您的数据:

>> data{1} % t 

ans = 

    0 
    0 
    0 

要收集您的数值数据,您可以遍历单元阵列,或者您可以使用textscan中的'CollectOutput'标志:

fid = fopen('data.dat'); 
header = fgetl(fid); 

data = textscan(fid, '%f %f %f %f %f %f %f %f %f %f %s', 'CollectOutput', true); 
fclose(fid); 

将输出一个1x2单元阵列,其中data{1}是你的数字阵列和data{2}是包含您的字符串单元阵列:

>> data{1} % Numeric data 

ans = 

     0 1.2712 0.8899 22.2458 265.2511 322.1539 -13.6281 -130.9860 0.1553 0.8898 
     0 1.2712 0.8899 22.2458 265.2511 322.1539 -13.6281 -130.9860 0.1553 0.8898 
     0 1.2712 0.8899 22.2458 265.2512 322.1539 -13.6281 -130.9860 0.1553 0.8898 

>> data{2} % Strings 

ans = 

    3×1 cell array 

    'phaet_000018' 
    'phaet_000044' 
    'phaet_000006' 
+0

这是一个很好的解释。谢谢你。 最后一个问题:如果您注意到,第一列如果是十进制数字0.0000,为什么matlab将它输出为0,尽管它被读为%f? – user3578925

+0

它只是MATLAB如何显示它,它仍然被存储为'double'。 – excaza