读取同一列中包含浮点数,整数和字符串的文本文件

时间:2015-05-20 07:32:57

标签: matlab text-files ascii

在Matlab中加载格式正确且分隔的文本文件相对简单,但是我很难阅读我必须阅读的文本文件。遗憾的是我无法更改源文件的结构,所以我必须处理什么我有。

基本文件结构是:

123 180 (two integers, white space delimited)
1.5674e-8
.
.
(floating point numbers in column 1, column 2 empty)
.
.
100 4501 (another two integers)
5.3456e-4 (followed by even more floating point numbers)
.
. 
.
.
45 String (A integer in column 1, string in column 2)
.
.
.

一个简单的

[data1,data2]=textread('filename.txt','%f %s', ...
                    'emptyvalue', NaN)

不起作用。 如何正确过滤输入数据?我在网上找到的所有例子和Matlab帮助到目前为止都处理结构良好的数据,所以我在哪里开始有点迷失。

因为我必须阅读一大堆这些文件> 100而不是通过每个文件中的每一行迭代。我希望有一个更快的方法。

编辑: 我在这里提供了一个示例文件:test.txt(谷歌驱动器)

2 个答案:

答案 0 :(得分:2)

我查看了您提供的文本文件,并试图得出一些一般性结论 -

  1. 当一行上有两个整数时,第二个整数对应于后面的行数。
  2. 你总是有(两个整数(A,B)后跟“B”浮标),重复两次。
  3. 之后你有一些自由格式的文本(或者至少,我之后无法推断出有关格式的任何有用的内容)。
  4. 这是一种混乱的格式,所以我怀疑会有什么好的解决方案。一些有用的一般原则是:

    • 当您需要阅读一行时,请使用fgetl(它会读取下一个换行符)
    • 当可以同时读取多行时使用textscan - 它比一次读取一行快得多。它有许多解析方法,值得了解(我建议输入doc textscan并阅读整篇文章)。
    • 如果有疑问,只需读取字符串中的行,然后在MATLAB中进行分析。

    在我的文件中,这是一个简单的文件解析器。它可能需要一些修改,因为你能够推断出更多关于文件结构的信息,但是在你给出的~700行测试文件上它相当快。

    我刚刚给出了变量虚拟名称,如“a”,“b”,“floats”等。您应该将它们更改为更符合您需求的内容。

    function output = readTestFile(filename)
    
        fid = fopen(filename, 'r');
    
        % Read the first line
        line = '';
        while isempty(line)
            line = fgetl(fid);
        end
        nums = textscan(line, '%d %d', 'CollectOutput', 1);
    
        a = nums{1}(1);
        b = nums{1}(2);
    
        % Read 'b' of the next lines:
        contents = textscan(fid, '%f', b);
        floats1 = contents{1};
    
        % Read the next line:
        line = '';
        while isempty(line)
            line = fgetl(fid);
        end
        nums = textscan(line, '%d %d', 'CollectOutput', 1);
    
        c = nums{1}(1);
        d = nums{1}(2);
    
        % Read 'd' of the next lines:
        contents = textscan(fid, '%f', d);
        floats2 = contents{1};
    
        % Read the rest:
        rest = textscan(fid, '%s', 'Delimiter', '\n');
    
        output.a = a;
        output.b = b;
        output.c = c;
        output.d = d;
        output.floats1 = floats1;
        output.floats2 = floats2;
        output.rest = rest{1};
    
    end
    

答案 1 :(得分:0)

您可以使用较低级别的函数逐行读取文件,然后手动解析每一行。

您可以像在C

中一样打开文件句柄
fid = fopen(filename);

然后您可以使用fgetl

读取一行
line = fgetl(fid);

字符串在空格上标记它可能是最好的第一遍,将每个部分存储在单元格数组中(因为矩阵不支持不规则数组)

colnum = 1;
while ~isempty(rem)
    [token, rem] = strtok(rem, ' ');
    entries{linenum, colnum} = token;
    colnum = colnum + 1;
end

然后你可以将所有内容包装在另一个while循环中以迭代行

linenum = 1;
while ~feof(fid)
    % getl, strtok, index bookkeeping as above
end

您是否最好在阅读时解析文件或先将其读入单元格数组,然后再将其翻过来。

您的单元格条目都将成为字符串(字符数组),因此您需要使用str2num将它们转换为数字。它可以很好地计算出格式,因此可能就是你所需要的。