sprintf - Linux OK but Windows Warning: Escaped character '\.' is not valid. See 'doc sprintf' for supported special characters.

I was using the following code inside a for loop to loop through multiple data folders and specify the folder as basically 'main\1', 'main\2', etc. on Ubuntu 16.04 Linux:
currentfolder = sprintf([DICOMdatafolder,'\%d'],loopPt);
It worked fine. In Windows 10, however:
Warning: Escaped character '\.' is not valid. See 'doc sprintf' for supported special characters.
Removing the \ causes the same warning, and so does the following:
currentfolder = sprintf(fullfile(DICOMdatafolder,'%d'),loopPt);
so I don't know what's wrong. Looking at the documentation, %d appears correct, and I don't understand what it is reading as an escape character. (I'm not sure what an escape character is, either: I thought it was used for syntax in a regular expression, but I didn't that was the case here.)
What is causing this warning and how do I resolve it to properly specify the folder as main/1, main/2, etc while looping through folders?
Below is a larger excerpt of the code:
DICOMdatafolder = fullfile('..','..','..','data','DICOMfiles');
NoPtfolders = CountNumberofFolders(DICOMdatafolder);
for loopPt = 1:NoPtfolders
currentfolder = sprintf([DICOMdatafolder,'%d'],loopPt);

1 Comment

This warning is resolved if I change the code instead to the following:
currentfolder = fullfile(DICOMdatafolder,num2str(loopPt));
Perhaps trying sprintf was overkill in this case. However, I would appreciate an answer to learn more about what the warning means, what caused it, and how to resolve it.

Sign in to comment.

 Accepted Answer

Use sprintf('%s%d',DICOMdatafolder,loopPt)
Remember that the path separator for windows is \ so your fullfile call is going to contain ..\..\ in the output but on Linux would instead have ../..
When you use the result in the first parameter of sprintf you are asking it to use those \ characters in the format specification.

4 Comments

Is it not better to "keep it simple" and in this case simply use
currentfolder = fullfile(DICOMdatafolder,num2str(loopPt));
? This approach is intuitive and results in working code. Is sprintf faster than num2str? open num2str lets me see the code but open sprintf only shows a commented introduction, so I am guessing sprintf is more fundamental and faster ...
Note also that Julian's suggestion to use filesep resulted in the same warning/error.
Yes, sprintf is faster than num2str.
If you know that DICOMdatafolder is a directory name, then you would use
fullfile(DICOMdatafolder, sprintf('%d', loopPt))
This is different than
sprintf('%s%d',DICOMdatafolder,loopPt)
because the output of fullfile() is not guaranteed to end in a path separator when a directory is being referred to -- and indeed usually will not end in a path separator on OS-X.
Your existing code
currentfolder = sprintf([DICOMdatafolder,'%d'],loopPt);
on OS-X would not have problems with \ characters because it was constructed using fullfile() which will use / for OS-X and Linux. However, because fullfile() does not end in / on OS-X (and probably Linux) then you would be jamming together the loopPt value as part of the last directory name. Always use fullfile() when you are putting together path strings and you expect that the first part is a complete directory name to be separated from the second part with a path separator. fullpath() takes care to check whether the first part happens to end in a path separator and does not put in the redundant separator in that case so it does not hurt for the first part to happen to end in a path separator already if you use fullfile()
I'm using the following to loop through folders name 1,2,... within DICOMfolder:
currentfolder = fullfile(DICOMdatafolder,sprintf('%u',loopPt));
Does it matter whether I use %d or %u? Because the folders are name 1,2,... not +1,+2,... it seemed more appropriate to use %u.
%d will never include the leading + unless you use %+d
The difference between %d and %u does not become important unless you are displaying uint64 that is larger than 2^54, and if you are then you had better be careful to explicitly make your for loop bounds uint64 as they default to double.

Sign in to comment.

More Answers (2)

The warning you get should be:
Escaped character '\%' is not valid.
What you want is a platform dependent
filesep
between path and the number, so in your case (Windows)
sprintf([DICOMdatafolder,'\\%d'],loopPt);
or (Linux)
sprintf([DICOMdatafolder,'\/%d'],loopPt);
or better, to be platform independent
sprintf([DICOMdatafolder, filesep, '%d'],loopPt);
which is essentially what fullfile does (go and do
edit fullfile
to see what i mean.
The escape character is the "\", which in the case of sprintf is for example used with \n or \t for newline and tab. The "%" itself is a special character for sprintf, but if you want a litersal "%", the way to go is %% and not \% as one would do in RegExp (which is stated in the help of sprintf)

2 Comments

sprintf([DICOMdatafolder, filesep, '%d'],loopPt);
results in the same warning (and subsequent error as the currentfolder is not set to main\number):
Warning: Escaped character '\.' is not valid. See 'doc sprintf' for supported special characters.
> In BlurPortalDose (line 34)
Undefined function or variable 'correctfolder'.
The subsequent error (which I didn't post in the OP) results from the currentfolder failing to be set properly.
sprintf([DICOMdatafolder, filesep, '%d'],loopPt);
results in the same error because \ is a special character called an escape character (just like %), and is not interpreted literally. What Julian Hapke showed you (but did not explain explicitly), is that to get an literal version of an escape character you need to double it (as explained in the sprintf help, and shown in Julian Hapke's examples). So you would need to do this:
sprintf([DICOMdatafolder, filesep, filesep, '%d'],loopPt);
Or avoid the whole problem by using a properly defined format string:
sprintf('%s%s%d',DICOMdatafolder,filesep,loopPt);
But I would definitely NOT recommend these as solutions! Use fullfile instead:
fullfile(DICOMdatafolder, sprintf('%d', loopPt))

Sign in to comment.

Well guys,
I am reading all the answers and comments and I am thinking about my problem as described in this question. What would you do if you did not write ANY "escape" character (eg. \U), but your script did not want to run because of the error message as mentioned in my question? Any wise ideas?
Regards
MP

Categories

Community Treasure Hunt

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

Start Hunting!