Why i get this following error when using dir in Matlab? - matlab

Matlab keep give me following error message :
??? Error using ==> dir
Argument must contain a string.
Error in ==> Awal at 15
x = dir(subDirs)
Below is my codes :
%MY PROGRAM
clear all;
clc;
close all;
%-----Create Database-----
TrainDB = uigetdir('','Select Database Directory');
TrainFiles = dir(TrainDB);
dirIndex = [TrainFiles.isdir];
[s subDirNumber] = size(dirIndex);
for i = 3:subDirNumber
subDirs = {TrainFiles(i).name};
subDirs = strcat(TrainDB,'\',subDirs);
x = dir(subDirs) %<-------Error Here
end
Is something wrong with the codes? Your help will be appreciated.
I'm sorry for my bad English.

The problem is with this line:
subDirs = {TrainFiles(i).name};
When you strcat on the next line, you are strcat-ing two strings with a cell containing a string. The result in subDirs is a cell containing a string which dir() apparently doesn't like. You can either use
subDirs = TrainFiles(i).name;
or
x = dir(subDirs(1))
I would recommend the first option.

When I run your code I get the error message:
??? Error using ==> dir
Function is not defined for 'cell' inputs.
What MATLAB is telling you is that when you call dir(subDirs) subDirs is a cell rather than a string which is what dir wants. Something like dir(subDirs{1,1}) will do what (I think) you want. I'll leave it to you to rewrite your code.

with subDirs = {TrainFiles(i).name}; you create a cell-array of stings. dir is not defined for that type. Just omit the {} around the name
BTW: Your code does not only list directories, but all files. Check find on the isdir attribute to get only directory's indices!

Related

Cannot create output file with saveas

i wrote that code
clear all;
clc;
addpath('C:\Users\John\Documents\MATLAB\code for yannis\anger(W)\');
h1 = dir('C:\Users\John\Documents\MATLAB\code for yannis\anger(W)\');
for i=3:numel(h1)
%disp(h1(i,1).name);
%disp(k);
three(h1(i,1).name);
end
and the three function is
function three(filename)
%disp(filename);
q = char(39);
filename = strcat(q,filename,q)
%disp(filename);
load(filename);
And i get that error:
Error using load
Unable to read file '03a01WaM.mat': No such file or directory.
Error in three (line 7)
load(filename);
Error in run_three (line 13)
three(h1(i,1).name);
i also wrote exist('03a01WaM.mat') and the function return 2
Does anyone has an idea, what am i doing wrong?
There are multiple issues with your code.
addpath is simply unnessecary.
You are using relative path, but not cd. You have to use the full path to access the files.
You are adding a apostrophe to the filename.
Correct code would be:
directory='C:\Users\John\Documents\MATLAB\code for yannis\anger(W)\'; %'
h1 = dir(directory);
for i=3:numel(h1)
filename=fullfile(directory,h1(i,1).name);
load(filename);
end

MATLAB dir without '.' and '..'

the function dir returns an array like
.
..
Folder1
Folder2
and every time I have to get rid of the first 2 items, with methods like :
for i=1:numel(folders)
foldername = folders(i).name;
if foldername(1) == '.' % do nothing
continue;
end
do_something(foldername)
end
and with nested loops it can result in a lot of repeated code.
So can I avoid these "folders" by an easier way?
Thanks for any help!
Edit:
Lately I have been dealing with this issue more simply, like this :
for i=3:numel(folders)
do_something(folders(i).name)
end
simply disregarding the first two items.
BUT, pay attention to #Jubobs' answer. Be careful for folder names that start with a nasty character that have a smaller ASCII value than .. Then the second method will fail. Also, if it starts with a ., then the first method will fail :)
So either make sure you have nice folder names and use one of my simple solutions, or use #Jubobs' solution to make sure.
A loop-less solution:
d=dir;
d=d(~ismember({d.name},{'.','..'}));
TL; DR
Scroll to the bottom of my answer for a function that lists directory contents except . and ...
Detailed answer
The . and .. entries correspond to the current folder and the parent folder, respectively. In *nix shells, you can use commands like ls -lA to list everything but . and ... Sadly, MATLAB's dir doesn't offer this functionality.
However, all is not lost. The elements of the output struct array returned by the dir function are actually ordered in lexicographical order based on the name field. This means that, if your current MATLAB folder contains files/folders that start by any character of ASCII code point smaller than that of the full stop (46, in decimal), then . and .. willl not correspond to the first two elements of that struct array.
Here is an illustrative example: if your current MATLAB folder has the following structure (!hello and 'world being either files or folders),
.
├── !hello
└── 'world
then you get this
>> f = dir;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
.
..
Why are . and .. not the first two entries, here? Because both the exclamation point and the single quote have smaller code points (33 and 39, in decimal, resp.) than that of the full stop (46, in decimal).
I refer you to this ASCII table for an exhaustive list of the visible characters that have an ASCII code point smaller than that of the full stop; note that not all of them are necessarily legal filename characters, though.
A custom dir function that does not list . and ..
Right after invoking dir, you can always get rid of the two offending entries from the struct array before manipulating it. Moreover, for convenience, if you want to save yourself some mental overhead, you can always write a custom dir function that does what you want:
function listing = dir2(varargin)
if nargin == 0
name = '.';
elseif nargin == 1
name = varargin{1};
else
error('Too many input arguments.')
end
listing = dir(name);
inds = [];
n = 0;
k = 1;
while n < 2 && k <= length(listing)
if any(strcmp(listing(k).name, {'.', '..'}))
inds(end + 1) = k;
n = n + 1;
end
k = k + 1;
end
listing(inds) = [];
Test
Assuming the same directory structure as before, you get the following:
>> f = dir2;
>> for k = 1 : length(f), disp(f(k).name), end
!hello
'world
a similar solution from the one suggested by Tal is:
listing = dir(directoryname);
listing(1:2)=[]; % here you erase these . and .. items from listing
It has the advantage to use a very common trick in Matlab, but assumes that you know that the first two items of listing are . and .. (which you do in this case). Whereas the solution provided by Tal (which I did not try though) seems to find the . and .. items even if they are not placed at the first two positions within listing.
Hope that helps ;)
If you're just using dir to get a list of files and and directories, you can use Matlab's ls function instead. On UNIX systems, this just returns the output of the shell's ls command, which may be faster than calling dir. The . and .. directories won't be displayed (unless your shell is set up to do so). Also, note that the behavior of this function is different between UNIX and Windows systems.
If you still want to use dir, and you test each file name explicitly, as in your example, it's a good idea to use strcmp (or one of its relations) instead of == to compare strings. The following would skip all hidden files and folder on UNIX systems:
listing = dir;
for i = 1:length(listing)
if ~strcmp(listing(i).name(1),'.')
% Do something
...
end
end
You may also wanna exclude any other files besides removing dots
d = dir('/path/to/parent/folder')
d(1:2)=[]; % removing dots
d = d([d.isdir]) % [d.isdir] returns a logical array of 1s representing folders and 0s for other entries
I used: a = dir(folderPath);
Then used two short code that return struct:
my_isdir = a([a.isdir]) Get a struct which only has folder info
my_notdir = a(~[a.isdir]) Get a struct which only has non-folder info
Combining #jubobs and #Tal solutions:
function d = dir2(folderPath)
% DIR2 lists the files in folderPath ignoring the '.' and '..' paths.
if nargin<1; folderPath = '.'; elseif nargin == 1
d = dir(folderPath);
d = d(~ismember({d.name},{'.','..'}));
end
None of the above puts together the elements as I see the question having being asked - obtain a list only of directories, while excluding the parents.
Just combining the elements, I would go with:
function d = dirsonly(folderPath)
% dirsonly lists the unhidden directories in folderPath ignoring '.' and '..'
% creating a simple cell array without the rest of the dir struct information
if nargin<1; folderPath = '.'; elseif nargin == 1
d = dir(folderPath);
d = {d([d.isdir] & [~ismember({d.name},{'.','..'})]).name}.';
end
if hidden folders in general aren't wanted the ismember line could be replaced with:
d = {d([d.isdir] & [~strncmp({d.name},'.',1)]).name}.';
if there were very very large numbers of interfering non-directory files it might be more efficient to separate the steps:
d = d([d.isdir]);
d = {d([~strncmp({d.name},'.',1)]).name}.';
We can use the function startsWith
folders = dir("folderPath");
folders = string({folders.name});
folders = folders(~startsWith(folders,"."))
Potential Solution - just remove the fields
Files = dir;
FilesNew = Files(3:end);
You can just remove them as they are the first two "files" in the structure
Or if you are actually looking for specific file types:
Files = dir('*.mat');

Create a blank text file from within a function in Matlab

I wnat to create a function:
function[check]=createFile(filename, matrix)
Where I create a blank text file with the name 'filename'.
Where later in the function inputs from 'matrix' can be put in and stored.
2 question:
1)How do I create just a blank .txt file?
2)I've had some problem with this in somewhat simular functions, but is there an easy way to get rid of the need to write apostrophes in the arguments when calling the function?(i.e: createFile(name,matrix) instead of createFile('name',matrix)
to create the text file just use:
fid = fopen('filename.txt','w')
and there is no way to avoid the apostrophies 'filename.txt' - as matlab would try to call a function filename.txt which it wouldn't find.
for your function you can use
function [check] = createFile(filename, matrix)
% filename contains string!
fid = fopen(filename,'w')`
if exist('fid')
check = true;
else
check = false;
end
... write your matrix to file.
end
2) but is there an easy way to get rid of the need to write apostrophes in the arguments when calling the function?(i.e: createFile(name,matrix) instead of createFile('name',matrix)
Yes: you can type
createFile name matrix
after you have included this in createFile.m:
function createFile(name,matrix)
matrix=evalin('caller',matrix);

dir(myFiles{m}) does't work MATLAB

myFiles = 1x7 cell
when I try
for m =1:numel(myFiles )
fil{m} = dir(myFiles {m});
fil{m}.bytes ;
end
This is not working
I got the error :
function is not defined for 'cell' inputs.
First of all you should mention the error message you get.
Now, besides that are some obvious problems:
myFiles {ii}
This is not valid syntax to index into a cell array. Perhaps removing the space helps.
Furthermore you loop over m and then use ii as an index.
Lastly you assign to fil everytime. In practice this means only the last result is stored. Perhaps assigning to fil(m) would suit your needs better.
The command dir will show you the content of a folder. As your variable is named "myFiles" I assume it contains filenames and not foldernames. So I think you're rather looking for a loop like this:
for ii = 1:numel(myFiles)
fil{ii} = which( myFiles{ii} )
end
which gives you an array with the full paths to your files. Or are you looking for the folders containing the files in "myFiles"? Then you can use:
for ii = 1:numel(myFiles)
fil{ii} = fileparts( which( myFiles{ii} ) )
end
returning you the corresponding folders.
regarding your comments:
the existence of the files/folders in "myFiles" is the only purpose?
Then you could do that:
for ii = 1:numel(myFiles)
fil(ii) = exist( which(myFiles{ii}), 'file' );
end
existMyFiles = logical(fil);
returning a logical array specifying the existence of your files.

How to read a lot of DICOM files with Matlab?

I am using a script which generate a collection of strings in a loop:
'folder1/im1'
'folder1/im2'
...
'folder1/im3'
I assign the string to a variable, when I try to execute the img = dicomread(file); function I get the following error:
Error using dicomread>newDicomread (line 164)
The first input argument must be a filename or DICOM info struct.
Error in dicomread (line 80)
[X, map, alpha, overlays] = newDicomread(msgname, frames);
Error in time (line 14)
img = dicomread(file);
However, using the command line I don't get errors: img = dicomread('folder1/im1').
The code is the next:
for i=1:6 %six cases
nameDir = strcat('folder', int2str(i));
dirData = dir(nameDir);
dirIndex = [dirData.isdir];
fileList = {dirData(~dirIndex).name}; % list of files for each directory
n = size(fileList);
cd(nameDir);
for x = 1:n(2)
img = dicomread(strcat(pwd(), '/', fileList(x)));
end
cd('..');
end
What could be the error?
You've figured it out by now, haven't you.
Based on what you've written, you test
img = dicomread('folder1/im1');
when what you are having trouble with is
img = dicomread(file);
You need to actually test the line you are having trouble with. I would recommend:
putting a break point in test.m a the line img = dicomread(file). When you get to that line you can see what file is equal to. Also do whos file to make sure it is of class char and not a cell array or something random.
If you still want help, edit your original post and show the code where you assign those strings to file and tell us what happens when you type img = dicomread(file) at the command prompt.