MATLAB won't let me change the value of a string
6 次查看(过去 30 天)
显示 更早的评论
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
0 个评论
回答(5 个)
Star Strider
2017-1-18
编辑:Star Strider
2017-1-18
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.
0 个评论
Image Analyst
2017-1-18
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 个评论
Image Analyst
2017-1-18
编辑:Image Analyst
2017-1-18
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.
Kelly Kearney
2017-1-19
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 个评论
Image Analyst
2017-1-19
编辑:Image Analyst
2017-1-19
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
2017-1-19
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.
Guillaume
2017-1-19
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.
0 个评论
Walter Roberson
2017-1-19
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 个评论
Guillaume
2017-1-19
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)');
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Characters and Strings 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!