How to build char* from array of char*
Please have a look at the following code:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
const char * cmd;
const char * help;
} CmdEnum;
static CmdEnum cmd_enum[] = {
{"help", "This help..."},
{"first", "The first command"},
{"second", "The second command"},
};
void main()
{
int i,n;
char *out = "";
n = sizeof(cmd_enum) / sizeof(CmdEnum);
for (i=0; i<n; i++)
{
char *oldOut = out;
CmdEnum cmd = cmd_enum[i];
asprintf(&out, "%s%s -> %s\n", oldOut, cmd.cmd, cmd.help);
if(i>0) free(oldOut);
}
printf("%s", out);
printf("Done.\n");
}
Is this a good way to build a text from the CmdEnum?
Is there a "nicer" way do definecmd
in the first place as to avoid the if(i>0) free...
?
Or am I doing something entirely wrong?
EDIT:
After reading larsmans' answer I modifiedmain
to:
int main()
{
int i,n, copied, siz;
char *out, *cursor;
siz = 1;// 1 for NUL char
n = sizeof(cmd_enum) / sizeof(开发者_JAVA技巧CmdEnum);
for (i=0; i<n; i++)
{
siz += strlen(cmd_enum[i].cmd) + strlen(cmd_enum[i].help) + strlen(":\n\t\n\n");
}
out = malloc(siz);
if(!out)
{
printf("Could not alloc!\n");
return 1;
}
cursor = out;
for (i=0; i<n; i++)
{
copied = snprintf(cursor, siz, "%s:\n\t%s\n\n", cmd_enum[i].cmd, cmd_enum[i].help);
if(copied < 0 || copied >= siz)
{
printf("snprintf failed: %i chars copied.\n", copied);
return 1;
}
cursor += copied;
siz -= copied;
}
printf("%s", out);
printf("Done.\n");
free(out);
return 0;
}
(Note: I also changed the output format...)
Is this a good way to build a text from the CmdEnum?
Yes, except that asprintf
is not portable (although you can define it easily in terms of snprintf
for platforms that don't have it) and you're not checking error returns. void main
isn't valid C btw.
Is there a "nicer" way do define cmd in the first place as to avoid the if(i>0) free...?
You could allocate the whole string beforehand.
size_t i, siz = 1; // 1 for NUL char
for (i=0; i<n; i++)
siz += strlen(cmd_enum[i].cmd) + strlen(cmd_enum[i].help) + strlen(" -> \n");
char *out = malloc(siz);
// check for errors
then build the string with snprintf
. This saves you some malloc
'ing and error checking in the loop.
精彩评论