I just realized that each field could possibly have more than just one ampersand. How would I take this into account if I were to modify post #6? A simple while loop would not work, as the memory needs to be reallocated as well. The following is my attempt; please correct me if I did something wrong.
Code:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void parse(const char *line, const char *user)
{
const char* end = line;
const char* start;
char* field;
int ampersand_count = 0;
size_t len, replen;
while ( isspace(*end) ) ++end;
start = end;
while ( *end != '\0' && !isspace(*end) ) ++end;
len = end - start;
replen = strlen(user);
field = malloc(len + 1);
if ( field )
{
char *ampersand;
sprintf(field, "%.*s", len, start);
ampersand_count = 0;
const char* traverse = start;
while (traverse != end) {
if (*traverse == '&') ++ampersand_count;
++traverse;
}
free(field);
field = malloc(len + ampersand_count * (userlen - 1) + 1);
if (field) {
sprintf(field, "%.*s", len, start);
while ((ampersand = strchr(field, '&'))) {
memmove(ampersand + replen, ampersand + 1, strlen(ampersand + 1));
memcpy(ampersand, user, replen);
}
}
printf("\"%s\"\n", field);
free(field);
}
}
int main(void)
{
parse("user1,user2,&,user4 group1,group2,group3 string1 string2 string3", "user3");
return 0;
}
/* my output
"user1,user2,user3,user4"
*/
I'm not particularly fond of this solution, primarily because I must traverse the string twice (once through char* traverse, the other through strchr). Can anyone post a cleaner or faster solution?