sprintf only get the first character in a string array

24 views (last 30 days)
Hi, I have 25 audio files of 5 different words and I am trying to get their mfcc's using two for loops. My code looks:
filename = ['asr','cnn','dnn','hmm','tts'];
for i=1:5
for j=1:5
fname = sprintf('%s%d',filename(1,i),j);
mfcc_i = mfcc(eval(fname), 44100);
I already have matrices like asr1, asr2...in the workspace. However I got the error like this:
Error using eval
Undefined function or variable 'a1'.
So it looks like sprintf() only reads the first character in the array of strings instead of the first string('asr'). Why does it happen and how I can fix this?

Accepted Answer

Stephen23 on 19 Oct 2018
Edited: Stephen23 on 19 Oct 2018
"Why does it happen and how I can fix this?"
Because [] is a concatenation operator, not a list operator as some beginners imagine. So your line
filename = ['asr','cnn','dnn','hmm','tts'];
is exactly equivalent to this:
filename = 'asrcnndnnhmmtts';
which is not very useful in your situation. Then inside the loop you simply access one of those characters using indexing:
filename(1,i) % get ONE character
You can fix this trivially by using a cell array to store those character vectors, but this does not resolve that fact that your code is vary badly designed: using eval to access variable names is one way that beginners force themselves into writing slow, complex, buggy code that is hard to debug. Read this to know why:
"I already have matrices like asr1, asr2... in the workspace."
DO NOT DO THIS! Magically accessing variable names is a bad way to write code. Presumably you did not sit and write out lots of variable name by hand, so they must have been imported/generated somehow, and that is exactly where you should FIX your badly designed code. For example, instead of load-ing directly into the workspace, you should load into an output variable (which is a structure):
S = load(...)
If you explain how those variables came into the workspace, we can show you better ways to write your code.

More Answers (1)

Walter Roberson
Walter Roberson on 19 Oct 2018
filename = ['asr','cnn','dnn','hmm','tts'];
is not an array of strings. It is exactly the same thing as
filename = horzcat('asr','cnn','dnn','hmm','tts');
which is going to produce
filename = 'asrcnndnnhmmtts';
String arrays use " instead of '
filename = ["asr", "cnn", "dnn", "hmm", "tts"];
If you are using a string array then you can simplify
fname = sprintf('%s%d',filename(1,i),j);
fname = filename(1,i) + j;
We firmly recommend against using eval.
Instead of naming your variables asr1 asr2 and so on, use a cell array for them, asr{1}, asr{2} and so on. You can use things like
asr = 1; cnn = 2; dnn = 3; hmm = 4; tts = 5;
soundata = cell(5, 5);
soundata{asr,1} = ....
soundata{hmm,3} = ....
for J = 1 : 5
for K = 1 : 5
mfcc_results{J,K} = mfcc(soundata{J,K}, 44100);


Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by