Suhaib Ahmad
Suhaib Ahmad

Reputation: 526

Matlab - Read multiple lines, where number of lines specified, from a text file and store in matrix

I have a text file, suppose myfile.txt, that stores floating point coordinates in following manner:

53
-464.000000 -20.000000 0.009000
-464.000000 -17.000000 0.042000
-464.000000 -13.000000 0.074000
-464.000000 -11.000000 0.096000
-464.000000 -8.000000 0.114000
...
...
...
42
380.000000 193.000000 7.076000
381.000000 190.000000 7.109000
383.000000 186.000000 7.141000
384.000000 184.000000 7.163000
384.000000 183.000000 7.186000
386.000000 179.000000 7.219000
...
...
...

the first line specifies the number of lines for the first set of coordinates, followed by that many lines. and then theres is another integer specifying the the number of lines for the next set of coordinates.

i.e. 1st line has 53, so next 53 lines are 1st set of coords(ending at line 54). Then line 55 has value 42, so next 42 lines are 2nd set of coords.

How can I read the text file such that i read 1st line, and the next 53 lines are read and stored in matrix. Then read 42 and the next 42 lines are read and stored? The text file is like this until EOF.

Upvotes: 0

Views: 936

Answers (3)

Rafael Monteiro
Rafael Monteiro

Reputation: 4549

You could do it with Low-Level File I/O, like this:

fid = fopen('myfile.txt', 'r');
matrix = {};
while ~feof(fid)
    N = fscanf(fid, '%d\n', 1);
    matrix{end + 1} = fscanf(fid, '%f\n', [3 N])';
end
fclose(fid);

Upvotes: 2

PieCot
PieCot

Reputation: 3639

My two cents:

function matrix_cells = import_coordinates(filename, startRow, endRow)
%IMPORT_COORDINATES Import numeric data from a text file as a matrix.
%   MATRIX_CELLS = IMPORT_COORDINATES(FILENAME) Reads data from text file FILENAME
%   for the default selection and store it into the array of cells MATRIX_CELLS.
%
%   MATRIX_CELLS = IMPORT_COORDINATES(FILENAME, STARTROW, ENDROW) Reads data from
%   rows STARTROW through ENDROW of text file FILENAME.
%
% Example:
%   matrix_cells = import_coordinates('coordinates.txt', 1, 15);
%
%    See also TEXTSCAN.

%% Initialize variables.
delimiter = ' ';
if nargin<=2
    startRow = 1;
    endRow = inf;
end

%% Format string for each line of text:
%   column1: double (%f)
%   column2: double (%f)
%   column3: double (%f)
% For more information, see the TEXTSCAN documentation.
formatSpec = '%f%f%f%[^\n\r]';

%% Open the text file.
fileID = fopen(filename,'r');

%% Read columns of data according to format string.
% This call is based on the structure of the file used to generate this
% code. If an error occurs for a different file, try regenerating the code
% from the Import Tool.
dataArray = textscan(fileID, formatSpec, endRow(1)-startRow(1)+1, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'EmptyValue' ,NaN,'HeaderLines', startRow(1)-1, 'ReturnOnError', false);
for block=2:length(startRow)
    frewind(fileID);
    dataArrayBlock = textscan(fileID, formatSpec, endRow(block)-startRow(block)+1, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'EmptyValue' ,NaN,'HeaderLines', startRow(block)-1, 'ReturnOnError', false);
    for col=1:length(dataArray)
        dataArray{col} = [dataArray{col};dataArrayBlock{col}];
    end
end

%% Close the text file.
fclose(fileID);

%% Post processing for unimportable data.
% No unimportable data rules were applied during the import, so no post
% processing code is included. To generate code which works for
% unimportable data, select unimportable cells in a file and regenerate the
% script.

%% Create output variable
matrix_temp = [dataArray{1:end-1}];

%% MY CONTRIBUTION ;)
% find rows with nan values
[i,~]=find(isnan(matrix_temp)); 
indexes=unique(i); 

%% Create output cell array
matrix_cells=cell(numel(indexes),1);

%% Fill cell array filtering out unuseful rows and parting original matrix
for i=1:1:numel(indexes)-1
    matrix_cells{i}=matrix_temp(indexes(i)+1:indexes(i+1)-1,:);
end
% Last matrix
matrix_cells{end}=matrix_temp(indexes(end)+1:size(matrix_temp,1),:);

The first part (reading and import of text file) of this function was autogenerated by MATLAB. I added only the code to split and save the matrix into a cell array.

I assume that coordinates do not contain nan values; morevoer, I do not check for consistency between the declared number of rows and the actual one for each block.

Here an example; the following is the file coordinates.txt

5
-464.000000 -20.000000 0.009000
-464.000000 -17.000000 0.042000
-464.000000 -13.000000 0.074000
-464.000000 -11.000000 0.096000
-464.000000 -8.000000 0.114000
3
380.000000 193.000000 7.076000
381.000000 190.000000 7.109000
383.000000 186.000000 7.141000
2
384.000000 184.000000 7.163000
384.000000 183.000000 7.186000
1
386.000000 179.000000 7.219000

Excute the function:

coordinate_matrices=import_coordinates('coordinates.txt')

coordinate_matrices = 

    [5x3 double]
    [3x3 double]
    [2x3 double]
    [1x3 double]

This is the content of every cell:

>> coordinate_matrices{1}

ans =

 -464.0000  -20.0000    0.0090
 -464.0000  -17.0000    0.0420
 -464.0000  -13.0000    0.0740
 -464.0000  -11.0000    0.0960
 -464.0000   -8.0000    0.1140

>> coordinate_matrices{2}

ans =

  380.0000  193.0000    7.0760
  381.0000  190.0000    7.1090
  383.0000  186.0000    7.1410

>> coordinate_matrices{3}

ans =

  384.0000  184.0000    7.1630
  384.0000  183.0000    7.1860

>> coordinate_matrices{4}

ans =

  386.0000  179.0000    7.2190

Upvotes: 0

Suhaib Ahmad
Suhaib Ahmad

Reputation: 526

fid = fopen('myfile.txt ', 'r');
ind = 1;
mycell = {};
while ~feof(fid)
    N = fscanf(fid, '%d\n', 1);
    matrix = fscanf(fid, '%f\n', [3 N]);
    matrix = transpose(matrix);
    cell{ind} = matrix;
    ind = ind + 1;
end
fclose(fid);

Upvotes: 0

Related Questions