Search code examples
matlabcsvprintfstring-formattingexport-to-csv

Adjusting string format in fprintf depending on numeric values


I want to export a numerical array as a .csv file. So, the simplified term looks like this:

fid = fopen('output.csv','wt')
toprint = [1.0, 1.1, 1.2, 1.3];
fprintf(fid, '%f, %f, %f, %f\n', toprint);
fclose(fid)

In this case there is no problem. I use %f in string format to maintain precision. However, sometimes, or rather usually, there are zeros in the array like this:

toprint = [1.0, 0, 0, 1.1];

In such situation, I want to adjust the string format to:

'%f, %d, %d, %f\n' % where "%f" were replaced by "%d" at the positions of the zeros

to reduce output file size since I do not need the precision of zero numbers. The original solution I applied was to detect data types through the array. If zero was detected, then concatenate '%d' onto string format. But it seems to be very inefficient.

What I am looking for is a efficient method to adjust string format depending on input data. Is there any way to achieve this?


Solution

  • Two approaches:

    1. You can use "%g" to simplify floating-point output when possible. This also shortens other whole numbers like 1.0 or 2.0, which may or may not be what you want
    2. Dynamically construct the format string based on the the values
    >> fprintf('%g %g %g %g\n', [1.0, 1.1, 1.2, 1.3])
    1 1.1 1.2 1.3
    >> fprintf('%g %g %g %g\n', [1.0, 1.1, 0, 1.3])
    1 1.1 0 1.3
    >> fprintf('%g %g %g %g\n', [1.0, 1, 0, 1.3])
    1 1 0 1.3
    

    Approach 2:

    >> a = [1.1 1.2 0 1.3]
    
    a =
    
        1.1000    1.2000         0    1.3000
    
    >> tokens = {'%f', '%d'}
    
    tokens = 
    
        '%f'    '%d'
    
    >> strformat = strcat(strjoin(tokens((a==0)+1), ', '), '\n')
    
    strformat =
    
    %f, %f, %d, %f\n
    
    >> fprintf(strformat, a)
    1.100000, 1.200000, 0, 1.300000