display all elements in a nested cell array (with character entries) - matlab

I have the following:
a =
{1x1 cell} {1x1 cell} {1x1 cell} {1x1 cell}
where:
a{:}
ans =
'a'
ans =
'a'
ans =
'c'
ans =
'a'
I want to have the characters: a a c a
Since I need the characters to print using fprintf
fprintf won't accept a{:}
If I do a{1}{:} will consider only the first character a
How to fix this? Thanks.

If you only need the character vector 'aaca', you can use this:
a = {{'a'}, {'a'}, {'c'}, {'a'}};
a_CharVector = cellfun(#(x) char(x), a);
If you want the character vector 'a a c a ', you can use regexprep to add the spaces:
a_CharVectorWithSpaces = regexprep((cellfun(#(x) char(x), a)), '(.)', '$1 ');
To print a a c a with spaces and newline you can use this:
fprintf([ regexprep((cellfun(#(x) char(x), a)), '(.)', '$1 '), '\n' ]);
Edit: unnecessary anonymous function removed. #(x) is unnecessary in this case.
To get character vector 'aaca' this works:
a_CharVector = cellfun(#char, a);
And to get character vector 'a a c a ' you can use this:
a_CharVectorWithSpaces = regexprep((cellfun(#char, a)), '(.)', '$1 ');
To printf a a c a with newline:
fprintf([ regexprep((cellfun(#char, a)), '(.)', '$1 '), '\n' ]);

Related

Matlab: Meaning of '\a' or "alarm" in sprintf/fprintf

In the documentations of sprintf and fprintf, in the list of special output format characters/operators, there is the '\a' character and they say it's "Alarm".
I tried printing it and it gives me an empty output.
>> sprintf('\a')
ans =
>>
What does it do?
It's the ASCII BEL (0x07) character:
>> sprintf('\a')+0
ans = 7
>> a = sprintf('\a')
a =
>> b = char(7)
b =
>> a==b
ans = 1
It's normally used to make the console beep, but it doesn't do anything in my Octave command window.

Proper string conversion with implicit data type in MATLAB

I have arbitrary strings that shall be converted to suited data types (i.e. scalar double, double array or string), depending on their content.
str2num() does its job when interpreting the status return value, but the function itself evaluates the content of the string which:
causes str2num('3-7') to be -4 (double), but I want to stick to '3-7' (char array)
is a severe security issue, since it can potentially execute any code
One workaround is to use str2double(), which does not end up with double arrays, but just scalars or strings. Unfortunately, isstrprop() is not really appropriate for this.
Example inputs (and outputs):
'123.4' -> 123.4 (double scalar) [covered by str2double() and str2num()]
abc' -> 'abc' (char array) [inherently covered by str2double() and str2num()]
'123,456' -> [123, 456] (double array) [covered by str2num() only]
'3-7' -> '3-7' (char array) [don't know how to cover]
use str2double and strsplit:
C = {'123.4','abc','123,456','3-7'};
for ii = 1:numel(C)
CC = strsplit(C{ii},',');
res = [str2double(CC)];
if isnan(res)
res = C{ii};
end
disp(res)
disp(class(res))
disp('****************')
end
shows:
123.4000
double
****************
abc
char
****************
123 456
double
****************
3-7
char
****************
Solution (thanks to #user2999345):
function res = str2impl(str, delimiter)
narginchk(1,2);
if isempty(str)
res = [];
return
end
if nargin < 2
delimiter = ',';
end
splits = strsplit(str, delimiter);
res = str2double(splits);
if any(isnan(res)) & ~strcmpi(str, 'NaN') % NaN not specifically requested
res = str;
end
ends up in
C = {'123.4','abc','123,456','3-7','NaN','',[]};
for ii = 1:numel(C)
r{ii,1} = str2impl(C{ii});
end
disp(r)
[ 123.4000]
'abc'
[1×2 double]
'3-7'
[ NaN]
[]
[]

Extract numbers from string in MATLAB

I'm working with sscanf to extract a number from a string. The strings are usually in the form of:
'44 ppm'
'10 gallons'
'23.4 inches'
but ocassionally they are in the form of:
'<1 ppm'
If I use the following code:
x = sscanf('1 ppm','%f')
I get an output of
1
But if I add the less than sign in front of the one:
x = sscanf('<1 ppm','%f')
I get:
[]
How can I write this code so this actually produces a number? I'm not sure yet what number it should print...but let's just say it should print 1 for the moment.
You can use regexp:
s= '<1 ppm';
x=regexp(s, '.*?(\d+(\.\d+)*)', 'tokens' )
x{1}
Demo :
>> s= {'44 ppm', '10 gallons', '23.4 inches', '<1 ppm' } ;
>> x = regexp(s, '.*?(\d+(\.\d+)*)', 'tokens' );
>> cellfun( #(x) disp(x{1}), x ) % Demo for all
'44'
'10'
'23.4'
'1'

Matlab) what should I put more with function for, sttrep, cell?

I want to make the results like this:
phraseblanks
phrasemat = Hello and how are you?
Hi there everyone!
How is it going?
WHazzup?
Phrase 1 had 4 blanks
Phrase 2 had 3 blanks
Phrase 3 had 2 blanks
Phrase 4 had 0 blanks
New phrasemat is :
Hello&and&how&are&you?
Hi&there&everyone!
How&is&it&going?
WHazzup?
so I made script "phraseblanks.m":
phrasemat = char('Hello and how are you?', ...
'Hi there everyone!', 'How is it going?', 'WHazzup?')
[r, c] = size(phrasemat);
for i = 1:r
phrasemat_new = cell(r, c);
howmany = countblanks(phrasemat(i, :));
fprintf('Phrase %d had %d blanks\n', i, howmany);
phrasemat(i,:) = strrep(phrasemat(i,:),' ','&')
phrasemat_new{i,:} = [phrasemat(i,:)];
end
fprintf('Changing one is %s\n', eval('phrasemat_new'));
script "countblanks.m":
function num = countblanks(phrase)
% countblanks returns the # of blanks in a trimmed string
% Format: countblanks(string)
num = length(strfind(strtrim(phrase), ' '));
end
and I keep having errors.
please help me..
I modified slightly your phraseblanks.m so that it works.
phrasemat = {'Hello and how are you?', ...
'Hi there everyone!', ...
'How is it going?', ...
'WHazzup?'};
r = numel(phrasemat);
phrasemat_new = cell(1, r);
for i = 1:r
howmany = countblanks(phrasemat{i});
fprintf('Phrase %d had %d blanks\n', i, howmany);
phrasemat{i} = strrep(phrasemat{i}, ' ', '&');
phrasemat_new(i) = phrasemat(i);
end
fprintf('Changing one is %s\n', phrasemat_new{:});
Obviously it could be written in a nicer, more "matlaby-way", but I didn't want to stride too far from your original version. Also you could consider using regular expressions, since if you have to spaces next to each other and you want to treat them as one blank space.

Prefix match in MATLAB

Hey guys, I have a very simple problem in MATLAB:
I have some strings which are like this:
Pic001
Pic002
Pic003
004
Not every string starts with the prefix "Pic". So how can I cut off the part "pic" that only the numbers at the end shall remain to have an equal format for all my strings?
Greets, poeschlorn
If 'Pic' only ever occurs as a prefix in your strings and nowhere else within the strings then you could use STRREP to remove it like this:
>> x = {'Pic001'; 'Pic002'; 'Pic003'; '004'}
x =
'Pic001'
'Pic002'
'Pic003'
'004'
>> x = strrep(x, 'Pic', '')
x =
'001'
'002'
'003'
'004'
If 'Pic' can occur elsewhere in your strings and you only want to remove it when it occurs as a prefix then use STRNCMP to compare the first three characters of your strings:
>> x = {'Pic001'; 'Pic002'; 'Pic003'; '004'}
x =
'Pic001'
'Pic002'
'Pic003'
'004'
>> for ii = find(strncmp(x, 'Pic', 3))'
x{ii}(1:3) = [];
end
>> x
x =
'001'
'002'
'003'
'004'
strings = {'Pic001'; 'Pic002'; 'Pic003'; '004'};
numbers = regexp(strings, '(PIC)?(\d*)','match');
for cc = 1:length(numbers);
fprintf('%s\n', char(numbers{cc}));
end;