hylovegj 发表于 2010-11-24 10:56:57

紧急求助:数据提取出错

本帖最后由 hylovegj 于 2010-11-24 11:00 编辑

我要提取test1.txt文件(见附件)中SA-MIN,SB-MIN列的数据,写了如下代码
fid = fopen('test1.txt','r');
i = 0;
while ~feof(fid)
    tline = fgetl(fid);
    if isempty(tline)
      continue;
    elseif isnan(str2double(strread(tline,'%s%*[^\n]','delimiter',' ')))
      continue;
    elseif isnan(str2double(strread(tline,'%*s%s%*[^\n]','delimiter',' ')))
      continue;
    else
      i = i + 1;
      if strncmp(tline,'0',1)
            a(i)= strread(tline,'%*s%*s%*s%*s%*s%*s%*s%*s%f','delimiter',' ');
      else
            a(i)= strread(tline,'%*s%*s%*s%*s%*s%f','delimiter',' ');
      end
    end
end
a_max = max(a)
fprintf('%d\n',a_max);
fclose(fid);但运行后总是提示
??? Improper assignment with rectangular empty matrix.
Error in ==> test1 at 16
            a(i)= strread(tline,'%*s%*s%*s%*s%*s%*s%*s%*s%f','delimiter',' ');
大家帮我看看是什么原因。
这只是我要从中提取数据的文件的一部分,所以必须跳过空行、非数据行,因此用到了多分支结构。

hylovegj 发表于 2010-11-24 11:05:44

我试着把test1.txt文件传上来,但论坛不支持此种类型的附件,只好传个图片格式的上来。

feynmand 发表于 2010-11-24 11:24:14

你数据不多,直接在上面代码里面贴文本出来。然后大家复制下来另存到txt里面就可以测试你的程序了,这样查找错误方便点。

xuxu1457 发表于 2010-11-24 11:33:00

a(i)= strread(tline,'%*s%*s%*s%*s%*s%*s%*s%*s%f','delimiter',' ');
用这个提取数据时候有一行不符合数据类型 可以看看是哪一行 在后面加上输出a(i)的语句

hylovegj 发表于 2010-11-24 11:52:56

S T R E S S E S   I N   B A R   E L E M E N T S          ( C B A R )
ELEMENT      SA1            SA2            SA3            SA4         AXIAL          SA-MAX         SA-MIN   M.S.-T
    ID.          SB1            SB2            SB3            SB4         STRESS         SB-MAX         SB-MIN   M.S.-C
0   405    9.586723E+01-8.551099E+01-9.586723E+01   8.551099E+01-3.034317E+01   6.552407E+01-1.262104E+02
             4.401001E+01-5.972002E+01-4.401001E+01   5.972002E+01                  2.937685E+01-9.006319E+01
0   406    7.573322E+01-5.255919E+01-7.573322E+01   5.255919E+01-1.925389E+01   5.647932E+01-9.498711E+01
             6.709827E+00-2.800086E+01-6.709827E+00   2.800086E+01                  8.746970E+00-4.725475E+01
0   407    4.960469E+01-2.965390E+01-4.960469E+01   2.965390E+01-8.284171E+00   4.132052E+01-5.788886E+01
            -1.731817E+01-1.038412E+00   1.731817E+01   1.038412E+00                  9.033998E+00-2.560234E+01
0   408    2.568021E+01-9.650702E+00-2.568021E+01   9.650702E+00   8.131817E-01   2.649340E+01-2.486703E+01
            -3.349285E+01   1.841787E+01   3.349285E+01-1.841787E+01                  3.430603E+01-3.267967E+01
0   409    5.079842E+00   7.309621E+00-5.079842E+00-7.309621E+00   8.094417E+00   1.540404E+01   7.847956E-01
            -4.305178E+01   3.125949E+01   4.305178E+01-3.125949E+01                  5.114620E+01-3.495736E+01
0   410   -1.202691E+01   2.075104E+01   1.202691E+01-2.075104E+01   1.352715E+01   3.427819E+01-7.223881E+00
            -4.708897E+01   3.864254E+01   4.708897E+01-3.864254E+01                  6.061613E+01-3.356182E+01
0   411   -2.562799E+01   3.079352E+01   2.562799E+01-3.079352E+01   1.713275E+01   4.792627E+01-1.366077E+01
            -4.665755E+01   4.157127E+01   4.665755E+01-4.157127E+01                  6.379030E+01-2.952480E+01
0   412   -3.596317E+01   3.763166E+01   3.596317E+01-3.763166E+01   1.892176E+01   5.655342E+01-1.870990E+01
            -4.253256E+01   4.084339E+01   4.253256E+01-4.084339E+01                  6.145433E+01-2.361080E+01
0   413   -4.317125E+01   4.139950E+01   4.317125E+01-4.139950E+01   1.889989E+01   6.207114E+01-2.427137E+01
            -3.516331E+01   3.691494E+01   3.516331E+01-3.691494E+01                  5.581482E+01-1.801505E+01
0   414   -4.713287E+01   4.196637E+01   4.713287E+01-4.196637E+01   1.706749E+01   6.420036E+01-3.006537E+01
            -2.466586E+01   2.991218E+01   2.466586E+01-2.991218E+01                  4.697968E+01-1.284469E+01
0   415   -4.738642E+01   3.886494E+01   4.738642E+01-3.886494E+01   1.342061E+01   6.080703E+01-3.396581E+01
            -1.092131E+01   1.972145E+01   1.092131E+01-1.972145E+01                  3.314206E+01-6.300832E+00
0   416   -4.315055E+01   3.129207E+01   4.315055E+01-3.129207E+01   7.949965E+00   5.110051E+01-3.520058E+01
             6.245852E+00   6.207766E+00-6.245852E+00-6.207766E+00                  1.419582E+01   1.704113E+00
0   417   -3.340014E+01   1.827023E+01   3.340014E+01-1.827023E+01   6.376137E-01   3.403776E+01-3.276253E+01
             2.672425E+01-1.064039E+01-2.672425E+01   1.064039E+01                  2.736186E+01-2.608664E+01
0   418   -1.711336E+01-1.293141E+00   1.711336E+01   1.293141E+00-8.487277E+00   8.626083E+00-2.560064E+01
             5.019623E+01-3.019936E+01-5.019623E+01   3.019936E+01                  4.170895E+01-5.868351E+01
0   419    6.782635E+00-2.813298E+01-6.782635E+00   2.813298E+01-1.948302E+01   8.649961E+00-4.761600E+01
             7.545555E+01-5.221180E+01-7.545555E+01   5.221180E+01                  5.597253E+01-9.493857E+01
0   420    4.344027E+01-5.922089E+01-4.344027E+01   5.922089E+01-3.061331E+01   2.860758E+01-8.983420E+01
             9.433521E+01-8.393719E+01-9.433521E+01   8.393719E+01                  6.372190E+01-1.249485E+02
1    MSC.NASTRAN JOB CREATED ON 22-NOV-06 AT 22:16:35                      NOVEMBER22, 2006MSC.NASTRAN9/23/03   PAGE   8
   DEFAULT                                                                                                                        
0                                                                                                            SUBCASE 1

hylovegj 发表于 2010-11-24 12:11:09

非零开头的数据行是本来右对齐的,上传之后就变样了,大家看的时候注意一下。此外,最后一行是空行,这也正是为什么要加上if isempty(tline)continue;语句的原因。

taohe 发表于 2010-11-24 20:28:39

看起来好像有点麻烦,数据不能被当做是完整的表格文本,有些行有缺失数据。

不过我觉得你可以考虑用textscan,使用它,你可以指定用特殊的数值比如“-Inf”来填充缺失的数据,这样你还是可以用最多数据行的格式编写格式符,textscan返回的是一个cell array,其中每个元素分别代表使用textscan读取文件时按照格式符所对应的列。你拿到想要的那列数据后在扔掉那些特殊的被填充的数值,应该就是想要读取的文件中的数据了。

不好意思,只是一点思路,自己也有若干事情需要处理,无法帮你调试程序。

hylovegj 发表于 2010-11-25 08:52:17

我把test1.txt传上来了,有空的朋友帮我调试一下哈!3Q。。。

lin2009 发表于 2010-11-25 10:49:43

clear all
clc;

fid = fopen('test1.txt','r');
i = 1;
j = 1;
while ~feof(fid)
    tline = fgetl(fid);
    A = sscanf(tline,'%g');
    if length(A) == 9 && A(1) == 0
      SA_MIN(i) = A(8);
      i = i + 1;
    elseif length(A) == 6
      SB_MIN(j) = A(6);
      j = j + 1;
    end
end
fclose(fid);
% Check & display the output data.
if i == j
    disp('ok');
    fprintf('%g,\t%g\n', );      
else
    disp('数据不完整');
end

qibbxxt 发表于 2010-11-25 11:42:49

本帖最后由 qibbxxt 于 2010-11-25 13:34 编辑

clear;clc;close all
M = importdata('test1.txt', ' ');
SAMIN=M.data(~isnan(M.data(:,8)),8);
SBMIN=M.data(2:2:end,5);
也可以用dlmread等

hylovegj 发表于 2010-11-25 15:01:38

qibbxxt版主和lin2009兄的帖子非常具有启发性。其实我最终的目的是要找到最后两列中绝对值最大的数据,在你们的帮助下,我写了如下代码解决了问题。
clear;clc;
fid = fopen('test1.txt');
str = 0;
MaxStr = 0;
while ~feof(fid)
    tline = fgetl(fid);
    data = sscanf(tline,'%g');
    if length(data) == 9
      str = max(abs());
    elseif length(data) == 6
      str = max(abs());
    end
    if str > MaxStr
      MaxStr = str;
    end
end
fclose(fid);
fprintf('%f\n',MaxStr);
clear;
非常感谢lin2009兄的提示,我还是第一次用sscanf函数。
qibbxxt 版主,您的代码非常简洁,能否麻烦您注释一下?小弟道行浅,理解起来有点费劲啊。。。

qibbxxt 发表于 2010-11-25 17:01:43

11# hylovegj
第一句话是读入数据
第二句话是去掉SAMIN空的NaN,因为每行的长度不等,所以中间存在NaN
第三句话是取第5列数据的偶数行

clear;clc;close all
M = importdata('test1.txt', ' ');
SAMIN=M.data(~isnan(M.data(:,8)),8:9);
SBMIN=M.data(2:2:end,5:6);
MaxValue=max(feval(@(y)y(:),abs()))

这是我根据你的需求修改的代码
页: [1]
查看完整版本: 紧急求助:数据提取出错