1
votes

I have a struct:

typedef struct _test{
   int a;
   int b;
   int c;
   float f_arr[16384];
}test_t;

that struct i need to write in csv format into a file. I thought i might use a snprintf function to put everything into one char buffer, but: i need to convert each value from f_arr:

   char f_t_str[30];
   char arr[16384*2][30];
   for (i=0; i< 16384; i++){
       sprintf(f_t_str, "%.8f" ,test_t->f_arr[i]);
       memcpy(arr[i*2], f_t_str, strlen(f_t_str));
       printf("%s\n",arr[i*2]);
       arr[i*2 + 1][0] = ',';
   }

so, if i now have my float array converted to one big string in arr, i can just make a:

char dest[16384*2 + 512];
snprintf(dest, 16384*2 + 512, "%d,%d,%d,%s", test_t->a, test_t->b, test_t->s, arr);

but as a result im having:

10,11,12,13.1

instead of:

10,11,12,13.1,13.2,14.4.... [16384] ... 16400.23

i suppose that during conversion from float to char sprintf adds '\0' at end of string, so next snprintf (the one after loop is finished) finishes after it meets that '\0' - first value from 'arr'. How to make it working ?

regards J.

2
I suppose a combination of sprintf along with strcat might work for you - Potato
You can use return value of snprintf to check how many characters were written and get rid of terminating null. - zoska

2 Answers

1
votes

Try something like the following? (It's a little rough and ready as it leaves a trailing comma.) See code run here - http://ideone.com/EnU6Sa

The code uses an extra pointer to point to the start of the float string you just wrote to the buffer. This way we can determine the string length and increase the pointer by this amount so that the trailing NULL is pointed to. Thus the next snprintf will overwrite that NULL with the next string and so on...

#include <stdio.h>

#define TEST_BUFFER_CHARS 255
#define DIM(x) (sizeof(x)/sizeof((x)[0]))

int main(void) 
{
    int i;
    char testBuffer[TEST_BUFFER_CHARS] = {'\0'};
    char *loc = testBuffer;
    size_t testBufferSpace = TEST_BUFFER_CHARS;
    size_t tempLen;
    float testFloats[] = { 1.1, 1.2, 1.3, 1.4 };

    for(i = 0; i < DIM(testFloats); ++i)
    {
        snprintf(loc, testBufferSpace, "%f, ", testFloats[i]);
        tempLen = strlen(loc);
        loc += tempLen;
    }

    printf(testBuffer);

    return 0;
}
1
votes

Since you need a CSV format, I assume that you redirect the output of the program to a CSV file. Under such a case, you probably don't have to deal with large memory, a simple printf would suffice. Hope this code helps.

#include <stdio.h>
int main()
{
        int i;

        struct a {
                char a;
                char b;
                char c;
                float f[10];
        };

        struct a my_struct;

        my_struct.a = 'a';
        my_struct.b = 'b';
        my_struct.c = 'c';

        for (i = 0; i < 10; i++)
                my_struct.f[i] = i * 1.1;

        printf("%c,%c,%c", my_struct.a, my_struct.b, my_struct.c);
        for (i = 0; i < 10; i++)
                printf(",%.8f", my_struct.f[i]);

        return 0;
}

Output

a,b,c,0.00000000,1.10000002,2.20000005,3.29999995,4.40000010,5.50000000,6.59999990,7.69999981,8.80000019,9.89999962