0
votes

I have been trying to read some numbers from formatted text file. I want to keep some number of columns from numerous columns, and I want to repeat it to the end of file (multiple rows or lines).

This is the code that I wrote to do that but it only reads one single line of the data.

fid = fopen ('L0512164529','r+');
num_ints = 47;
num_rows = 50;
features = struct;

format =['L%d,',repmat('%f,' , 1 , num_ints-1),'%f'];
[r_dat,l] = textscan(fid, format, num_rows);
features.name=r_dat{1};
features.bodyposfeat=[r_dat{2:end}];

fclose(fid);

Every line starts with a number with starting L. The first two rows of the file are:

L0512164529,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.1376599,-0.4387758,0.4723490,0.751‌​9389,0.4742642,-0.8703301
L0512164529,0.0001816,0.0000005,-0.0005697,-1.0843741,0.0001816,0.0000005,-0.000‌​5697,-1.0843741,0.1433973
2
Give an example of the first couple of lines of your file. - Phil Goddard
L0512164529,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.1376599,-0.4387758,0.4723490,0.7519389,0.4742642,-0.8703301..... L0512164529,0.0001816,0.0000005,-0.0005697,-1.0843741,0.0001816,0.0000005,-0.0005697,-1.0843741,0.1433973..... These are first two rows of the text. Every line starts with a number with starting L. - CanCam
Your lines have variable columns? - excaza
You can also try fid = fopen(file), then use a while loop: while ~feof data(k,:) = fread(fid);k=k+1; end - Adriaan
If the lines have different numbers of columns, then textscan is not the right tool. - gariepy

2 Answers

0
votes

Make sure that you are using the correct number of %f format specifiers in your format string. It looks like you probably need to use the following format statement:

format =['L%d,',repmat('%f,' , 1 , num_ints-2),'%f'];  %% changed to ( num_ints - 2)

assuming that num_ints is the number of columns. When I tried your code with your sample data, it worked when I change num_ints to 14 since your examples only have 16 columns and the first one is specified separately with L%d,. When I increase num_ints above 14, it only parses 1 line of the file.

So to be clear, if num_ints is the number of columns, including the first column that has the L-name, then using num_ints-2 in the format string creation should work.

0
votes

Here's another way of doing it, if you have a variable number of columns in your file.

filename = 'temp.txt'
fid = fopen(filename, 'rt');
if fid < 0
    error('Error opening file %s\n', filename); % exit point
end

desired_number_of_columns = 48;  %% 1 for the name, and 47 for the data
number_of_rows = 1385;  %% data structure won''t have this many rows, because some will be skipped

features.name=zeros(number_of_rows,1);
features.bodyposfeat=zeros(number_of_rows, desired_number_of_columns-1);

cntr = 1
while true
    tline = fgetl(fid);  %% read file one line at a time
    if ~ischar(tline), break; end; % break out of loop at end of file

    splitLine = strsplit(tline, ',');  %% separate into columns
    if (length(splitLine) ~= desired_number_of_columns)  %% check for the correct number of columns
        continue;
    end

    features.name(cntr) = str2num(splitLine{1}(2:end)); %% chop off first character and convert to number; does not check for 'L' specifically
    features.bodyposfeat(cntr, 1:desired_number_of_columns-1) = str2double(splitLine(2:end));  %% convert strings to numbers and save the rest of the columns as data
    cntr = cntr + 1;
end

%% optional - delete extra rows in the data structure that were never populated
features.name(cntr:end) = [];
features.bodyposfeat(cntr:end,:) = [];

fclose(fid)