Stefan
Stefan

Reputation: 444

MATLAB: How to load an array without delimiter from file

I have been using the load function until now to load my space separated files into arrays in matlab. However this wastes lots of space for me since my values are either 0 or 1. Thus instead of writing files like

0 1 1 0 
1 1 1 0

I removed the spaces to create half as big files like:

0110
1110

However now load doesn't work correctly any more (creates a matrix I think with only the first number, so 2x1 instead of 2x4). I looked around with importdata, reading the file line by line and lots of other stuff but I couldn't find a clear solution. So essentially I want to read a matrix from a file which doesn't have a delimiter. Every number is an element of the array

Does anyone know of a clean way to do this? Thanks

Upvotes: 2

Views: 1687

Answers (4)

Amro
Amro

Reputation: 124563

Here is one way:

data.txt

0110
1110

MATLAB

%# read file lines as cell array of strings
fid = fopen('data.txt','rt');
C = textscan(fid, '%s', 'Delimiter','');
fclose(fid);

%# extract digits
C = cell2mat(cellfun(@(s)s-'0', C{1}, 'Uniform',false));

result:

C =
     0     1     1     0
     1     1     1     0

If you are really concerned about memory, maybe you cast as boolean: C = logical(C) as 0/1 are the possible values.

Upvotes: 6

Steve
Steve

Reputation: 4097

An alternate form of Amro's solution would be either

fid = fopen('data.txt','r');
C = textscan(fid, '%1d%1d%1d%1d');
fclose(fid);
M = cell2mat(C)

Or

fid = fopen('data.txt','r');
M_temp = textscan(fid, '%1d');
fclose(fid);
M = reshape(M_temp{1}, 2,4)

These are slightly different from Amro's solution as the first reads in a %1d format number (1 character integer) and returns a cell array C that can be converted using a much simpler cell2mat command. The second bit of code reads in only a vector of those values then reshapes the result---which works okay if you already know the size of the data but may need additional work if not.

If your actual files are very large you may find that one of these ways is faster, although it is hard to tell without actually running them side-by-side.

Upvotes: 0

Christopher Chiche
Christopher Chiche

Reputation: 15335

Inspired from this question: Convert decimal number to vector, here is a proposition, but I don't think it will work for large "numbers":

arrayfun(@str2double, str);

Upvotes: 0

Pablo
Pablo

Reputation: 8644

Adapted from the example here:

function ret = readbin()
  fid = fopen('data.txt');
  ret = [];

  tline = fgetl(fid);
  while ischar(tline)
      if isempty(ret)
        ret = tline;
      else
        ret = [ret; tline];
      end
      tline = fgetl(fid);
  end

  % Turn char '0' into numerical 0
  ret = ret - 48;

  fclose(fid);
end

Subtracting 48 (ASCII code for '0') you get a numeric matrix with 1's and 0's in the appropriate places. This is the output I get at the end of the function:

K>> ret
ret =
     0     1     1     0
     1     1     1     0
K>> class(ret)
ans =
double

Upvotes: 1

Related Questions