MATLAB won't let me change the value of a string

9 views (last 30 days)
I have a matrix of strings with a predeclared value, that will be changed in a for-loop later on Here's the code declaring the matrix:
TOTAL_VIEWPOINTS = 91;
vSet = repmat('base value',[TOTAL_VIEWPOINTS,1]);
So it declares a 91x1 matrix of the word "base value". Next I have
for i = 1:TOTAL_VIEWPOINTS
vSet(i) = ['value', i];
end
I'get the errors "In an assignment A(:) = B, the number of elements in A and B must be the same." at the line of code where I try to change vSet. I've tried everything like doing vSet(i,1) or even just setting it as 'value' without any additional information. It gives me the same error. The only thing that works is if I set it as a single letter such as 'v'... also when I do class(vSet) it reports it as a char
I'm running MATLAB R2015a with PsychToolBox on a Windows 7

Answers (5)

Star Strider
Star Strider on 18 Jan 2017
Edited: Star Strider on 18 Jan 2017
I’m not certain what you want to do. You need to allow for a specific number of columns.
See if this does what you want:
for i = 1:TOTAL_VIEWPOINTS
vSet(i,:) = sprintf('value%02d', i);
end
EDIT The '%02d' format descriptor is necessary if you want ‘TOTAL_VIEWPOINTS’ to go to 91 and not throw an error.

Image Analyst
Image Analyst on 18 Jan 2017
Because it's an array of strings, vSet must be a cell array, not a character array. Use braces:
for i = 1:TOTAL_VIEWPOINTS
vSet{i} = sprintf('value%d', i);
end
  4 Comments
Marco Sama
Marco Sama on 18 Jan 2017
another question is how come repmat sets vSet as a character array and not a string?
Image Analyst
Image Analyst on 18 Jan 2017
Edited: Image Analyst on 18 Jan 2017
Who said anything about repmat??? I didn't. You probably pre-declared it as some other kind of array. You should/can use cell() instead, or simply get rid of your repmat() call.
I just ran this and it runs beautifully:
TOTAL_VIEWPOINTS = 10;
vSet = cell(TOTAL_VIEWPOINTS, 1);
for i = 1:TOTAL_VIEWPOINTS
vSet{i} = sprintf('value%d', i);
end
Please post all 5 lines of code, and the COMPLETE error message, not a small snippet of it. I need all the red text, not just some of it.

Sign in to comment.


Kelly Kearney
Kelly Kearney on 19 Jan 2017
Note that your initial code doesn't declare a 91x1 matrix of the word "base value", as you claim it does.
TOTAL_VIEWPOINTS = 91;
vSet = repmat('base value',[TOTAL_VIEWPOINTS,1]);
Look at vSet:
>> whos vSet
Name Size Bytes Class Attributes
vSet 91x10 1820 char
It creates a 91 x 10 character array. 2D character arrays are usually not the best choice, because they only work when every row of the array has the same number of characters.
>> vSet(1,:) = 'value 1' % try to put 1 x 7 char into 1 x 10 slot
Subscripted assignment dimension mismatch.
>> vSet(1,:) = 'value 1 ' % pad with space to make it work
vSet =
value 1
base value
base value
base value
...
As everyone has commented already, it's much easier to work with cell arrays of strings:
vSet = cell(TOTAL_VIEWPOINTS,1);
[vSet{:}] = deal('base value');
for ii = 1:TOTAL_VIEWPOINTS
vSet{ii} = sprintf('value %d', ii);
end
>> vSet(1:10)
ans =
'value 1'
'value 2'
'value 3'
'value 4'
'value 5'
'value 6'
'value 7'
'value 8'
'value 9'
'value 10'
  3 Comments
Image Analyst
Image Analyst on 19 Jan 2017
Edited: Image Analyst on 19 Jan 2017
The vSet/deal line is not needed. If you get rid of that, Kelly's answer and mine are identical - a call to cell() and a for loop assigning the cells with sprintf(). It didn't work before because, like I said, you tried to use repmat. If you get rid of repmat, like I recommended, and use the code I, and Kelly, gave, it works fine.
Kelly Kearney
Kelly Kearney on 19 Jan 2017
Yes, the preallocation of 'base value' to all the entries is unnecessary in both the original example and my solution, since they get rewritten immediately.
I left it in there in case the real code involved some additional steps between the initial assignment and the rewriting. If it does, and the 'base value' placeholders are important, then the deal line demonstrates how one would preallocate a cell array with matching values.

Sign in to comment.


Guillaume
Guillaume on 19 Jan 2017
There are 2 (3 since R2016b) different ways to store strings in matlab, each with their pros and cons.
  • A 2D char array as you started doing
TOTAL_VIEWPOINTS = 91;
vSet = repmat('base value',[TOTAL_VIEWPOINTS,1]);
Note that this creates a 91x10 matrix of type char. Indexing works exactly the same way as for matrices of numbers, so if you want to get the string on line i you use:
vSet(i, :) %not vSet(i) which returns just one character.
Same as matrices of numbers, all rows must have the same number of columns, you can't have one string shorter or longer than the other.
  • A cell array of 1D char array
TOTAL_VIEWPOINTS = 91;
vSet = repmat({'base value'},[TOTAL_VIEWPOINTS,1]);
This creates a 91x1 cell array where each cell contains a 1xnchar char array. The length of the string in each cell can be different. To access the ith string:
vSet{i}
You can use either method. Star's answer show you how to do it with a 2D char array, Image Analyst's answer how to do it with a cell array of 1D char array
  • Note that it's better to say char array instead of string since R2016b now has a proper string type which is not a char array and is a lot more intuitive to use (your code would have worked without error if you'd used R2016b strings).
---
Also note that the syntax ['somechararray' somenumber] does not create the char array 'somechararray somenumber'. You have to use sprintf or num2str to convert the number into a char array. Again R2016b simplifies this, the string type understands that the number needs to be converted to string.

Walter Roberson
Walter Roberson on 19 Jan 2017
There is another approach using the new "string" data type:
TOTAL_VIEWPOINTS = 91;
vSet = strings(TOTAL_VIEWPOINTS,1);
for i = 1:TOTAL_VIEWPOINTS
vSet(i) = ['value', str2num(i)];
end
  5 Comments
Guillaume
Guillaume on 19 Jan 2017
Marco said he's using R2015a in his question.
@Marco, as I wrote in my answer the string type is new as of R2016b.
An even easier way to generate the wanted array of strings in R2016b is:
vSet = string('Value') + (1:TOTAL_VIEWPOINTS)'
or if "Value01" is preferred over "Value1":
vSet = compose('Value%02d', (1:TOTAL_VIEWPOINTS)');

Sign in to comment.

Categories

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!