num2str for strict string lengths
15 views (last 30 days)
Show older comments
I have an array of numbers with varying orders of magnitude that I want to convert to strings that are of fixed lengths. The string lengths are strict as the FEM solver I am using (NASTRAN) uses character counts to split strings into separate fields. I have tried fiddling around with the format specifiers but I have not found one that is robust enough for my application.
An as example, if my desired string length is 8, and the input number is 123, I can just use sprintf('%8s', num2str(123)). However if the input number is -12345678, the same method will give me '-12345678' which is 9 characters long, whereas the desired string is '-1.2E+07'. Similarly, '123E6' gives me '1234000000' which is also longer than desired, whereas I would want '1.23E+09'.
I see the main issue is that the field width specifier does not recognise the negative sign and the exponent as part of the width. Is there a quick solution for this or would I need to set up a bunch of conditional statements to iteratively do num2str, check the resulting string length, and reduce the precision until it is of the desired length?
1 Comment
Guillaume
on 24 Jan 2018
Unless there's something on the FileExchance I'm afraid you're going to have to write it yourself as none of the num2str, sprintf format specifiers can do what you want nor is it something supported by Java or .Net (which you could have used directly in matlab).
Answers (1)
Jan
on 24 Jan 2018
The real problem is importing text files with a fixed width for numbers. This is such an idiotic format! Even if you get this managed to write such a file, '-1.2E+07' is a very poor representation of -12345678: Only 2 significant digits! Ugly.
The only real solution is to contact the authors of NASTRAN and ask for a better file import. Maybe there is one already, e.g. in binary format?
But you are asking for writing a text file with 8 characters per element. This does not work with sprintf directly, and num2str is only a wrapper for this function. Note that '-1.2E+07' could be written as '-1.234E7' to have 2 more valid digits, and '-12345E3' wins another digit.
function c = sprintf8(d)
c = sprintfc('%8g', d); % Undocumented sprintf into cell string
len = cellfun('length', C);
for k = find(len > 8)
mag = ceil(log10(abs(d(k))));
neg = d(k) < 0;
if ...
... yeah
end
end
end
Sorry, I thought about it for a while and it is not trivial. For considering negative and positive values as well as very high and low magnitudes, overflow and underflow, a lot of exceptions are required. An exhaustive test must confirm the quality of the output. This is more than I can write in the forum currently - I cannot run Matlab at the moment. Perhaps the posted fragment helps you to write it by your own. Or it convinces you to use a reliable format for the file.
See Also
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!