Filter löschen
Filter löschen

Replace text in a struct with new values

5 Ansichten (letzte 30 Tage)
Michael Boyle
Michael Boyle am 15 Okt. 2021
Bearbeitet: dpb am 16 Okt. 2021
I have a struct where each row is a line from a text file. I am trying to replace values in a given row with new ones.
idx = 1;
new_value = 0.6411;
text_file(idx).text = '* .57735 .57735 .57735';
text_file(idx).text = strrep(text_file(idx).text,num2str(cell2mat(textscan(text_file(idx).text(9:25),'%f'))),num2str(new_value));
I am trying to keep the struct formatted like the text file so it can be written out into a new file when the replacement is complete. When I run these lines it doesn't change the value

Antworten (1)

dpb
dpb am 16 Okt. 2021
The problem is the string you're building for the substitution doesn't match the actual string in the struct substring owing to the peculiarities of C printf formatting string behavior for floating point values (and hence for fprintf and friends in MATLAB which are derived from the C i/o RTL).
Illustration of problem follows --
>> text_file(idx).text(9:25) % the substring you're selecting
ans =
'.57735 .'
>> num2str(cell2mat(textscan(text_file(idx).text(9:25),'%f'))) % what your conversion to string produces
ans =
'0.57735'
>>
num2str and all variants based on the C conversion formatting produce the leading 0 in front of the decimal point. This means that string doesn't match the string in the text which is
>> text_file(idx).text
ans =
'* .57735 .57735 .57735'
>>
The most brute-force but least modification to the existing code to make it work would be
>> strrep(text_file(idx).text,strrep(num2str(cell2mat(textscan(text_file(idx).text(9:25),'%f'))),'0.','.'),num2str(new_value,5))
ans =
'* 0.6411 0.6411 0.6411'
>>
which just does an internal string replacement of "0." with "." first.
I'd suggest the above can be simplified some by using the low-level sscanf instead of textscan
>> strrep(text_file(idx).text,strrep(num2str(sscanf(text_file(idx).text(9:25),'%f')),'0.','.'),num2str(new_value))
ans =
'* 0.6411 0.6411 0.6411'
>>
which gets rid of the cell returned by textscan in lieu of the double directly.
Alternatively, use some of the new-fangled string functions --
>> strrep(text_file(idx).text,extractBetween(text_file(idx).text(9:25),'.',' '),extractAfter(string(new_value),'.'))
ans =
"* .6411 .6411 .6411"
>>
  2 Kommentare
dpb
dpb am 16 Okt. 2021
Bearbeitet: dpb am 16 Okt. 2021
OBTW, if you keep the first solution, NB: that you've then introduced a leading "0." into the file that wasn't there before and then your substitution pattern removing it will end up inserting a second as
strrep(text_file(idx),'.6411','0.1234')
equivalent for a next time through case effective string would result in
0.6411 --> 0.0.1234
because it is replacing only the .6411 substring but the new string without a fixup will have the 0. leading substring in it. Again, the brute-force solution to that is to wrap the formatting expression in the strrep() to eliminate the leading zero same as for the substituted string. I didn't bother for the example above.
If, as it appears to be, this is a fixed-width formatted text file, I think instead of doing what you're doing I'd save it as a straight double array instead of text and rewrite it in its entirety with the desired formatting when needed.
Then all the substitutions can be done numerically with logical addressing and all the string manipulations go away completely.
dpb
dpb am 16 Okt. 2021
Or, alternatively to the above, one could keep the numeric array and then just do blanket character substitution into the text file image of the indexed locations to change overwriting the full field width instead of doing character substitution.
The above just treating as numeric and writing on demand still seems the simpler solution without seeing the full problem to be solved, however.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Characters and Strings finden Sie in Help Center und File Exchange

Produkte


Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by