1

I am using C++ to deal with string operation for long time but for some reason I have to write a code in C. I know that in C, I have to allocate the memory first before string operation. I am going to convert the array of integer to a big string, e.g.

int data[]={1, 102, 3024, 2, 3, 50234, 23} => "1,102,3024,2,3,50234,23"

I am using sprintf to convert each number in the array to string and use strcat to concatenate each substring

char *s, *output_string;
int i, N;
// N is the size of the array and given as parameter of a function
for (i=0; i<N; i++)
{
  sprintf(s, "%d", data[i]);
  strcat(output_string, s);
}

But it doesn't work. I wonder to use those functions sprintf and strcat, do I have to allocate the memory first? But the number of digits of the data[i] is varied so how can I tell how much memory I should assigned in advance? Also, how can I tell how much memory in total I have to allocate for output_string in advance? Thanks

4

3 回答 3

5

Yes, you need to allocate space for both the intermediate and final result first.

Let's assume (for the sake of argument) that each int can result in a maximum of 10 digits of output:

char intermediate[11];

char *result = malloc(input_count * 11+1);

for (int i=0; i<input_count;i++) {
    sprintf(intermediate, "%d", data[i]);
    strcat(result, intermediate);
    strcat(result, ",");
}

If you want to badly enough, you can use log10 to compute the number of digits that will be produced by each number, then allocate only the space necessary rather than allocating on a worst-case basis like I've done here.

Also note that in most cases, you'd probably be better off with snprintf instead of sprintf, if it's available. This lets you limit the amount of output produced, ensure against overflowing the buffer you provide.

于 2013-08-09T22:06:05.177 回答
2

In C you need to allocate the memory for strings first.

Luckily, snprintf() gives you the ability to do this easily (for C at least).

char *s, *output_string;
int i, N;
// Count size for output_string
int output_size = 0;
for (i=0; i<N; i++) {
  output_size += snprintf(NULL, 0, "%d", data[i]);
}

// Allocate space
output_string = malloc(output_size + 1);

// Now fill it
for (i=0; i<N; i++) {
  int new_size = snprintf(NULL, 0, "%d", data[i]);
  s = malloc(new_size + 1); // Extra space for null terminator
  sprintf(s, "%d", data[i]);
  strcat(output_string, s);
  free(s);
}
于 2013-08-09T22:07:33.300 回答
2

strcat in a loop runs O(N2). Even today that should be in reflexive-"nope" territory.

int need = 1; /* for the trailing nul */
for ( int n = 0; n < N; ++n )
        need += snprintf(0,0,"%s%d", n?",":"", data[n]);

{
        int used = 0;
        char *obuf = malloc(need);
        if ( !obuf ) return 0;

        for ( int n = 0; n < N; ++n )
                used += snprintf(obuf+used,need-used,"%s%d", n?",":"", data[n]);
        return obuf;
}
于 2013-08-09T23:03:46.983 回答