You'll need to do this in two steps, first calculate the total size to hold the string, then allocate it and compose the string. Could be done in a function like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
static char * matrix2D_to_string(const double *matrix, size_t rows, size_t columns)
{
const char format[] = "%f";
const char column_separator[] = " ";
const char row_separator[] = "\n";
int *column_widths = NULL;
size_t r = 0, c = 0;
char *buffer = NULL, *p = NULL;
size_t size = 0;
if (!rows || ! columns) {
errno = EINVAL;
return NULL;
}
// calculate maximum width for each column
column_widths = (int *)calloc(columns, sizeof(*column_widths));
for (r = 0; r < rows; ++r) {
for (c = 0; c < columns; ++c) {
char buf[256];
int width = sprintf(buf, format, matrix[r * columns + c]);
if (width > column_widths[c]) {
column_widths[c] = width;
}
}
}
// calculate total buffer size...
// ... values
for (c = 0; c < columns; ++c) {
size += column_widths[c] * rows;
}
// ... column separators
size += (columns - 1) * strlen(column_separator);
// ... row separators
size += (rows - 1) * strlen(row_separator);
// ... nul terminator
++size;
// make the string
buffer = (char *)malloc(size);
p = buffer;
for (r = 0; r < rows; ++r) {
if (r) {
strcpy(p, row_separator);
p += strlen(row_separator);
}
for (c = 0; c < columns; ++c) {
if (c) {
strcpy(p, column_separator);
p += strlen(column_separator);
}
int width = sprintf(p, format, matrix[r * columns + c]);
p += width;
if (width < column_widths[c]) {
width = column_widths[c] - width;
memset(p, ' ', width);
p += width;
}
}
}
*p = '\0';
// cleanup
free(column_widths);
return buffer;
}
int main()
{
double M[3][2]={{1.2,3.4},{3.14,2.718},{100.999,0.000005}};
char *s = matrix2D_to_string((const double *)M, ARRAY_SIZE(M), ARRAY_SIZE(M[0]));
puts(s);
free(s);
return 0;
}
This prints:
1.200000 3.400000
3.140000 2.718000
100.999000 0.000005