Just a few alternate thoughts (and I'll think about FSCANF over the week end a little more).
=== Using REGEXP (available in almost all languages):
.. and the following content (to illustrate the flexibility):
1 A ABC
2 B ABC
3 C ABC DEF
4 D ABC
5 E ABC FGH
6 F ABC
7 G ABC
8 H ABC
9 I ABC
10 J ABC
Code:
>> buffer = fileread('data.txt') ;
>> pattern = '(?<Column1>\d+)\s(?<Column2>\w+)\s+(?<Column3>.*?)[\r\n]' ;
>> n = regexp(buffer, pattern, 'names')
n =
1x10 struct array with fields:
Column1
Column2
Column3
>> n(2)
ans =
Column1: '2'
Column2: 'B'
Column3: 'ABC'
>> n(3)
ans =
Column1: '3'
Column2: 'C'
Column3: 'ABC DEF'
>> str2double({n(:).Column1})
ans =
1 2 3 4 5 6 7 8 9 10
etc .. here I used named tokens and a struct array output, just for the fun of it. I don't think that it is what you are looking for, but I just wanted to illustrated a regexp-based approach for the record.
=== Reading array of chars and converting to cell array based on position of spaces and \n and/or \r:
... to update if asked by OP.
=== Using FSCANF:
.. and the following, more regular content:
1 A ABC
2 B ABC
3 C ABC
4 D ABC
5 E ABC
6 F ABC
7 G ABC
8 H ABC
9 I ABC
10 J ABC
Code:
fid = fopen('data_regular.txt', 'r') ;
data = cell(1e6, 3) ;
rCnt = 0 ;
while ~feof(fid)
rCnt = rCnt + 1 ;
data{rCnt,1} = fscanf(fid, '%d', 1) ;
data{rCnt,2} = fscanf(fid, '%s', 1) ;
data{rCnt,3} = fscanf(fid, '%s', 1) ;
end
fclose(fid) ;
data = data(1:rCnt,:) ;
Using this, we get:
>> data
data =
[ 1] 'A' 'ABC'
[ 2] 'B' 'ABC'
[ 3] 'C' 'ABC'
[ 4] 'D' 'ABC'
[ 5] 'E' 'ABC'
[ 6] 'F' 'ABC'
[ 7] 'G' 'ABC'
[ 8] 'H' 'ABC'
[ 9] 'I' 'ABC'
[10] 'J' 'ABC'
Note that EOF should be tested a little better (and not every three FSCANF, which assumes a well formed file). The whole could be in a TRY/CATCH statement otherwise.
=== Using FGETL + SSCANF:
It is more complicated than FSCANF, because the later moves forward an internal file pointer/counter as it reads the content, so the next read operation takes what follows. SSCANF doesn't work like this and you have to indicate what to extract and what to skip in the format. To illustrate:
>> s = '12 A ABC' ;
>> sscanf(s, '%d')
ans =
12
>> sscanf(s, '%s')
ans =
12AABC
>> sscanf(s, '%*d %s', 1)
ans =
65
>> char(sscanf(s, '%*d %s', 1))
ans =
A
>> char(sscanf(s, '%*d %s %*s'))
ans =
A
>> char(sscanf(s, '%*d %*s %s'))
ans =
A
B
C
>> char(sscanf(s, '%*d %*s %s')).'
ans =
ABC
Best Answer