How to avoid empty brackets using textscan?

6 views (last 30 days)
I am having trouble with the textscan function. I have a text file that contains only the information "Study Date: 8/30/2013 10:07:30 PM" (without the quotes). I am trying to use the textscan function to get the date and time information and put each number into a separate cell in an array. When I do this using the code below, for some reason it puts empty square brackets into each cell instead of the numbers. Please advise...
I am using this code to open my file and obtain the mm dd yy hh mm ss variables:
%%Startup clear data
clear all;
close all;
clc;
%%Find "event file" and get basic start time.
% Ask user to locate "date file"
[c,pathc] ...
= uigetfile({'C:\Users\HP\OneDrive\Documents\1 School Stuff\*.txt'} ...
, 'Select the Sandman Event List:');
% Send file info and open the file
file=[pathc c];
fid=fopen(file);
% Read basic date and time data about the file
% read the time for start of study
StudyDate ...
= textscan(file,'%*s %*s %d %d %d %d %d %d %*s',1,'delimiter',{':','/'});
fclose(fid);

Accepted Answer

per isakson
per isakson on 1 Jan 2015
Edited: per isakson on 2 Jan 2015
The documentation on Whitespace and Delimiter together with space in Formatspec is difficult to interpret (IMO). However, specifying Delimiter overtakes the default value, i.e whitepace. In this example space is needed as a delimiter.
Documentation says:
textscan interprets repeated delimiter characters as separate delimiters,
and returns an empty value to the output cell.
However, in my example below "one or more" spaces are obviously interpreted as one delimiter. That's probably because space is included in the values of both Whitespace and Delimiter. The documentation says little (read nothing) about the effect of different values of Whitespace. (And I don't know C.)
Try this example
str = 'Study Date: 8/30/2013 10:07:30 PM';
cac = textscan( str,'%*s%*s%d%d%d%d%d%d%*s', 'Delimiter',{':','/',' '} );
cac
it returns
cac =
[8] [30] [2013] [10] [7] [30]
&nbsp
In response to comment
  • I replaced the space in the filename by underscore. Spaces in filenames has caused too many "Cannot open file" over the years.
  • There is a tab after "Date:". This file has two columns, name and value, separated by tab.
fid = fopen( 'study_date.txt' );
cac = textscan( fid, '%*s%*s%d%d%d%d%d%d%*s' ...
, 'Delimiter',{':','/',' ','\t'} );
fclose( fid );
cac
returns
cac =
[0] [8] [30] [2013] [10] [7]
ERROR I'll be back
Of course! &nbsp ...Date:\t has two delimiters in a row. This is too tricky to my taste.
fid = fopen( 'study_date.txt' );
cac = textscan( fid,'%*s%*s%d%d%d%d%d%d%*s' ...
, 'Delimiter', {':','/',' ','\t'} ...
, 'MultipleDelimsAsOne', true );
fclose( fid );
cac
returns
cac =
[8] [30] [2013] [10] [7] [30]
Conclusion
I have ended up in an overly complicated solution to the literal question. The reason, I think, is that I was concentrating on effects of various values Whitespace and Delimiter and made stepwise fixes.
DONE
&nbsp
In response to the comment by Star Strider
IMO: this is a much better way to read the file
fid = fopen( 'study_date.txt' );
cac = textscan( fid,'%s%s', 'Delimiter',{'\t'} );
fclose( fid );
vec = datevec( cac{2}, 'mm/dd/yyyy HH:MM:SS PM' )
returns
vec =
2013 8 30 22 7 30
>>
&nbsp
In R2014b textscan( ... 'formatSpec' ... ) has a new feature
%{fmt}D &nbsp Read a string in the same way as %q above, and then
convert to a datetime value. fmt describes the format of the input
string. The fmt input is a string of letter identifiers that is a
valid value for the Format property of a datetime.
  6 Comments
per isakson
per isakson on 1 Jan 2015
Edited: per isakson on 1 Jan 2015
Kevin,
Thank you for your comment!
I missed that the value of file was the filespec rather than the file-ID. And textscan missed it because it takes a string or a file-ID.
However, are you sure that your code works correctly? My version of your code doesn't return the expected result.
fid = fopen( 'study_date.txt' );
cac = textscan( fid,'%*s%*s%d%d%d%d%d%d%*s', 'Delimiter',{':','/'} );
fclose( fid );
cac
returns
cac =
[30] [2013] [10] [7] [30] [0x1 int32]
The second %*s matches the first number of the string, i.e. 8. Replace %*s%*s by %*s.
&nbsp
And another comment
Had you used %s%s instead of %*s%*s you would probably have spotted the mistake directly.
fid = fopen( 'study_date.txt' );
cac = textscan( 'study_date.txt','%s%s%d%d%d%d%d%d%s' ...
, 'Delimiter',{':','/'} );
fclose( fid );
cac
returns
cac =
Columns 1 through 6
{1x1 cell} {0x1 cell} [0x1 int32] [0x1 int32] [0x1 int32] [0x1 int32]
Columns 7 through 9
[0x1 int32] [0x1 int32] {0x1 cell}
and
>> cac{1}
ans =
'study_date.txt'
%*s%*s is kind of premature optimization.
Kevin
Kevin on 1 Jan 2015
I guess my final answer was a mix and match... I did end up including all three string calls as you had in your example. Again, thank you for your help!

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!