Textscan reading in floats and str2num dropping ending zeros

MATLAB VERSION: R2007a - I know...my company is up on the times.
I'm trying to read in data from a tab delimited text file that looks like:
ABCDEF 2012.190.18465.356 0 TRUE
MKJIJN 2012.190.19305.376 b7 183
My current scan string is:
SCAN_STR = '%s\t%f.%f\t%s\t%s\t%*s';
TEMP = textscan(FID, SCAN_STR, 'delimiter', '\t');
Matlab reads in the data as (sample of first to save time):
TEMP{1} = 'ABCDEF'
TEMP{2} = 2012.19
TEMP{3} = 18465.365
TEMP{4} = '0'
TEMP{5} = 'TRUE'
Why does it drop the ending zero for TEMP{2}? 19 vs. 190 is a big difference. Is there any way for me to make sure the ending zero remains?
When I try to read it in as a string:
SCAN_STR = '%s\t%s\%s\t%s\t%*s';
All are strings. Now:
TEMP{2} = '2012.190.18465.356'
I split it using:
YRDY = cellfun(@(x)x(1:8),TEMP{2},'Un',0);
YRDY = '2012.190'
Using str2num:
YRDYnum = cellfun(@(x)str2num(x), YRDY, 'Un',0);
YRDYnum = 2012.19
Why does this happen? There has to be some way for me to keep the ending zero.
Thanks, Mike

 Accepted Answer

If you read the year-day combo string in as a number, or convert from string to number, it's going to treat the value like a number. And in that case, 2012.19 is the same as 2012.190. You probably want to split the year and day values apart before converting to a number:
% Recreate your test
str = sprintf('%s\t%s\t%s\t%s\n', 'ABCDE','2012.190.18465.356', '0', 'TRUE', 'MKJIJN', '2012.190.19305.376', 'b7', '183')
str =
ABCDE 2012.190.18465.356 0 TRUE
MKJIJN 2012.190.19305.376 b7 183
% Read everything as strings
data = textscan(str, '%s%s%s%s', 'delimiter', '\t');
% Parse dates
yrday = data{2};
yrday = cellfun(@(x) regexp(x, '\.', 'split'), yrday, 'uni', 0);
yrday = cat(1, yrday{:});
yrday = cellfun(@str2num, yrday);

2 Comments

Ok. Thats what I was going forward with. Then that presents a problem with my TEMP{3}. For me TEMP{3} is time. Now if that ends in a zero it could mess up my results. Is the only way around this to separate my time into sec.ms? I guess I'm confused on how MATLAB sees 2012.19 the same as 2012.190. Why does MATLAB drop the ending zero? MATLAB doesn't see zero as a place holder/number so it assumes its not needed?
It's a little roundabout, but you can put the seconds and milliseconds back together prior to converting to a number
yrday = data{2};
yrday = cellfun(@(x) regexp(x, '\.', 'split'), yrday, 'uni', 0);
yr = cellfun(@str2num, yrday(:,1));
day = cellfun(@str2num, yrday(:,2));
sec = cellfun(@(x,y) str2num([x '.' y]), yrday(:,3), yrday(:,4));
There's probably a way to split only along the first two instances of \. in the regular expression, but I don't know it off the top of my head.
As for why it behaves this way, I think the confusion is arising over the use of the period as a delimiter vs its use as a decimal point. When converting from string to number, Matlab assumes . is the decimal, so there's no need to hold on to trailing zeros after a decimal point (Matlab doesn't assume significant digits or anything like that). In your case, it seems as though the . is being used for both purposes: to delimit years, days, and seconds; and as a decimal point in the seconds. So you need to break apart the strings first, then convert to numeric form once you have removed all non-decimal .'s.

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!