代码之家  ›  专栏  ›  技术社区  ›  Wrzlprmft

将文本文件加载为二维字符串数组,而不指定列数

  •  3
  • Wrzlprmft  · 技术社区  · 7 年前

    假设我有一个纯文本文件 test.dat :

    foo bar baz
    qux ham spam
    

    我知道,我想将其作为二维单元数组加载到倍频程(或Matlab,如果必要的话)中,保留以空格和换行符编码的结构。根据我对 the documentation ,应采取以下措施:

    format = '%s';
    file = fopen('test.dat');
    data = textscan(file,format);
    fclose(file);
    disp(data);
    

    但是,这仅将数据加载为一维数组:

    {
      [1,1] = 
      {
        [1,1] = foo
        [2,1] = bar
        [3,1] = baz
        [4,1] = qux
        [5,1] = ham
        [6,1] = spam
      }
    }
    

    显式指定 Delimiter , Whitespace EndOfLine 没有帮助(那么后者有什么意义?);使用其他加载函数(如 textread dlmread . work正在使用什么 format = '%s%s%s' 但这需要我以某种方式确定列的数量,函数应该能够自己做到这一点。

    因此,我问: 有没有 内置的 我想要的函数? 我对自己编写这样一个函数的方法不感兴趣,我相信我可以做到这一点,但这正是我想要避免的(因为我需要用它来演示良好的实践,从而不需要重新发明轮子)。

    相关问答;As(所有操作都需要知道列数):

    4 回复  |  直到 7 年前
        1
  •  5
  •   Wolfie Radu Stefan    7 年前

    您可以使用 readtable

    data = readtable('test.txt', 'ReadVariableNames', false, 'Delimiter', ' ')
    

    输出:

    Var1     Var2      Var3 
    _____    _____    ______
    
    'foo'    'bar'    'baz' 
    'qux'    'ham'    'spam'
    

    如果你想要一个单元格,而不是一张桌子,你可以使用

    data = table2cell( data );
    
    >> data = {'foo'    'bar'    'baz' 
               'qux'    'ham'    'spam'}
    

    我不确定 可读性 是一种倍频程法 on GitHub 但我没有要检查的安装。它于2013b引入Matlab。


    您可以使用较低级别的操作,逐行阅读

    fid = fopen('test.txt','r');
    data = {};
    while ~feof(fid)
        line = fgets(fid);       % Read line
        A = strsplit(line, ' '); % Split on spaces
        data(end+1, :) = A;      % Append to output
    end
    fclose(fid);
    
    >> data = {'foo'    'bar'    'baz' 
               'qux'    'ham'    'spam'}
    

    此方法假定每行 data 将具有相同数量的元素(每行中分隔符的数量相同)。如果你不能假设,那么更安全的方法是 data{end+1,1} = A ,然后拆分行。

    此方法中使用的唯一非低级文件I/O函数是 strsplit . 这是内置的 Octave Matlab .

        2
  •  3
  •   rahnema1    7 年前

    您可以使用八度音阶 csv2cell 从软件包中 io :

    pkg load io
    result = csv2cell('test.dat',' ')
    
        3
  •  0
  •   Aristotelis    7 年前

    我建议您看看fgetl()或fgets()函数。 基本上,您可以读取文件的行,然后使用textscan()应用代码并获取“列”。

        4
  •  0
  •   NZMark    5 年前

    我也有同样的问题。可读性。m在Matlab中的速度很慢,fgetl示例正在循环中调整大小。 但也许可以接受的解决方案是基于以下论坛帖子: https://de.mathworks.com/matlabcentral/answers/476483-how-to-use-textscan-on-a-cell-array-without-a-loop

    因此,至少在较新的Matlab中:

    fid=fopen(file,'r');
    data=textscan(fid,'%s','Delimiter','\r\n');
    fclose(fid);
    data=split(data{1},';',1); 
    

    我还没有测试split。m表示大数据速度。