【问题标题】:Matlab to read in fix-width text fileMatlab读取固定宽度的文本文件
【发布时间】:2016-01-18 02:46:19
【问题描述】:

我有一个如下的文本文件:

TestData                                                                     

  6.84 11.31 17.51 22.62 26.91 31.98 36.47 35.85 28.47 20.57 10.50  6.37  test1
  0.24  2.62  4.94  7.17 10.39 15.37 18.73 18.29 12.26  6.46  1.15 -0.33  test2
 68.47 95.04156.07218.39304.31320.22311.69269.22203.01135.60 68.18 55.09  test3

 68.47 95.04156.07218.39304.31320.22311.69269.22203.01135.60 68.18 55.09  test4
...

如您所见,前两行是要忽略的 cmets。在以下几行中,每行末尾也有注释。每个数字都采用 %6f 的形式。另外,中间有空行。

我想将所有数字读入一个矩阵以绘制图表。我尝试使用 textscan,但在忽略最后一列、空白行和读入连接的数字时遇到了问题(例如,行中的一些数字:test4)。

这是我现在拥有的代码:

data=dir('*.txt');
formatspecific='%6f%6f%6f%6f%6f%6f%6f%6f%6f%6f%6f%6f';
for i=1:length(data);
    TestData1=data(i).name;
    tempData=textscan(TestData1,formatspecific,'HeaderLines',2);
end

任何人都可以帮助制作示例代码来改进 textscan 部分?

【问题讨论】:

  • 贴出你已有的代码
  • 为什么不指定格式的最后一个字符串?这就是您需要做的所有事情,然后只需删除结果中的字符串。
  • 即使我将字符串放入格式中,我也只是在输出中得到了 13 个空白 []。你知道为什么吗?
  • importdata 不起作用,我得到“使用 TEXTSCAN 或 FREAD 获取更复杂的格式”。

标签: matlab fixed-width textscan


【解决方案1】:

要使用textscan 读取文件,您必须在调用textscan 之前“打开”它并在之后“关闭”它;你应该使用

  • fopen打开输入文件
  • fclose关闭输入文件

textscan 返回一个cellarray,其中包含从输入文件中读取的内容;由于您正在读取多个文件,因此您应该更改管理 textscan 返回的单元阵列的方式,实际上,就像现在在您的代码中一样,数据在每次迭代时都会被覆盖。

一种可能是将数据存储在struct 的数组中,例如,2 fields:输入文件的名称和数据。

另一种可能性是生成一个struct,每个字段都包含从输入文件中读取的数据;可以自动生成文件名。

另一种可能性是将它们存储到矩阵中。

之后,您可以找到一个脚本,其中已经实现了这三个替代方案。

代码更新(根据收到的评论)

为了能够正确读取95.04156.07等数据为95.04156.07,格式说明符应由%6f修改为%6.2f

% Get the list of input data
data=dir('input_file*.txt');
% Define the number of data column
n_data_col=12;
% Define the number of heared lines
n_header=2;
% Build the format specifier string
% OLD format specifier
formatspecific=[repmat('%6f',1,n_data_col) '%s']
% NEW format specifier
formatspecific=[repmat('%6.2f',1,n_data_col) '%s']
% Initialize the m_data matrix (if you know in advance the numer of row of
% each input file yoiu can define since the beginning the size of the
% matrix)
m_data=[];
% Loop for input file reading
for i=1:length(data)
   % Get the i-th file name
   file_name=data(i).name
   % Open the i-th input file
   fp=fopen(file_name,'rt')
   % Read the i-th input file
   C=textscan(fp,formatspecific,'headerlines',n_header)
   % Close the input file
   fclose(fp)
   % Assign the read data to the "the_data" array struct
   the_data(i).f_name=file_name
   the_data(i).data=[C{1:end-1}]
   % Assign the data to a struct whos fileds are named after the inout file
   data_struct.(file_name(1:end-4))=[C{1:end-1}]
   % Assign the data to the matric "m_data
   m_data=[m_data;[C{1:end-1}]]
end

输入文件

TestData                                                                     

  6.84 11.31 17.51 22.62 26.91 31.98 36.47 35.85 28.47 20.57 10.50  6.37  test1
  0.24  2.62  4.94  7.17 10.39 15.37 18.73 18.29 12.26  6.46  1.15 -0.33  test2
 68.47 95.04156.07218.39304.31320.22311.69269.22203.01135.60 68.18 55.09  test3

 68.47 95.04156.07218.39304.31320.22311.69269.22203.01135.60 68.18 55.09  test4

输出

m_data =

  Columns 1 through 7

    6.8400   11.3100   17.5100   22.6200   26.9100   31.9800   36.4700
    0.2400    2.6200    4.9400    7.1700   10.3900   15.3700   18.7300
   68.4700   95.0400  156.0700  218.3900  304.3100  320.2200  311.6900
   68.4700   95.0400  156.0700  218.3900  304.3100  320.2200  311.6900

  Columns 8 through 12

   35.8500   28.4700   20.5700   10.5000    6.3700
   18.2900   12.2600    6.4600    1.1500   -0.3300
  269.2200  203.0100  135.6000   68.1800   55.0900
  269.2200  203.0100  135.6000   68.1800   55.0900

希望这会有所帮助。

【讨论】:

  • 谢谢。这非常清楚,非常有帮助。但是 textscan 忽略了前导空格,并且矩阵 C 对于行 test4 是不正确的。例如 test4 中的第三个数字是 56.072,但应该是 156.07。
  • 抱歉这个迟到的答案。 我已经更新了代码,现在95.04156.07 被正确读取为95.04156.07。从您的评论中不清楚您是否要“识别”空行(例如test3test4 之间的行。如果是这样,您想在矩阵中插入什么?
  • 谢谢。空行可以留0,只是被删除。该程序运行良好。
  • 不客气,有点像最初的错误。也许您可能想接受答案以结束问题。
猜你喜欢
  • 1970-01-01
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多