i want modify string this:—
mainstring="", toupdate="abc" -> return# "abc=1" mainstring="abc=1", toupdate="abc" -> return# "abc=2" mainstring="abc=2", toupdate="abc" -> return# "abc=3" mainstring="abc=3", toupdate="xyz" -> return# "abc=3:xyz=1" mainstring="abc=3:xyz=1", toupdate="xyz" -> return# "abc=3:xyz=2" mainstring="abc=3:xyz=2", toupdate="xyz" -> return# "abc=3:xyz=3"
i have following function:
void updatestring(char *mainstring, char toupdate[20]) { char *pdata[50][2]; char *saveptr1=null; int i=0,j=0,nispresentflag=0; unsigned int cdrcnt=1; char workbuf1[200]; char workbuf[200]; memset(workbuf,0,200); memset(workbuf1,0,200); if(strlen(mainstring)>0) { strcat(mainstring,":"); } strcpy(workbuf1,mainstring); pdata[i][0]=strtok_r(workbuf1,"=",&saveptr1); pdata[i][1]=strtok_r(null,":",&saveptr1); if(pdata[i][0]) {i++;pdata[i][0]=null; pdata[i][1]=null;} while((pdata[i][0]=strtok_r(null,"=",&saveptr1))) { pdata[i][1]=strtok_r(null,":",&saveptr1); i++; } for(j=0;j<i;j++) if(strncmp(toupdate,pdata[j][0],strlen(pdata[j][0]))==0) { cdrcnt=atoi(pdata[j][1]); cdrcnt+=1; sprintf(pdata[j][1],"%d",cdrcnt); nispresentflag=1; break; } if(nispresentflag==1) for(j=0;j<i;j++) sprintf(workbuf,"%s%s=%s:",workbuf,pdata[j][0],pdata[j][1]); else sprintf(workbuf,"%s%s=%d:",mainstring,toupdate,1); workbuf[strlen(workbuf)-1]='\0'; memset(mainstring,0,200); strcpy(mainstring,workbuf); }
curiously, function working, causing core dump segfault.
what wrong code? better way can manage above task?
==============================================================================
edit 1
string declaration:
char mainstring[200];
the call like:
updatestring((char*)&mainstring,"abc");
preliminary observation
given test code:
static void chkit(char *s, char *u) { printf("[%s] && [%s]", s, u); updatestring(s, u); printf(" ==> [%s]\n", s); } int main(void) { char mainstring[200] = ""; chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "xyz"); chkit(mainstring, "xyz"); chkit(mainstring, "xyz"); chkit(mainstring, "def"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "xyz"); chkit(mainstring, "abc"); chkit(mainstring, "ghi"); return 0; }
the output is:
[] && [abc] ==> [abc=1] [abc=1] && [abc] ==> [abc=2] [abc=2] && [abc] ==> [abc=3] [abc=3] && [xyz] ==> [abc=3:xyz=1] [abc=3:xyz=1] && [xyz] ==> [abc=3:xyz=2] [abc=3:xyz=2] && [xyz] ==> [abc=3:xyz=3] [abc=3:xyz=3] && [def] ==> [abc=3:xyz=3:def=1] [abc=3:xyz=3:def=1] && [abc] ==> [abc=4:xyz=3:def=1] [abc=4:xyz=3:def=1] && [abc] ==> [abc=5:xyz=3:def=1] [abc=5:xyz=3:def=1] && [abc] ==> [abc=6:xyz=3:def=1] [abc=6:xyz=3:def=1] && [abc] ==> [abc=7:xyz=3:def=1] [abc=7:xyz=3:def=1] && [abc] ==> [abc=8:xyz=3:def=1] [abc=8:xyz=3:def=1] && [abc] ==> [abc=9:xyz=3:def=1] [abc=9:xyz=3:def=1] && [abc] ==> [abc=10:=3:def=1] [abc=10:=3:def=1] && [xyz] ==> [abc=10:=3:def=1:xyz=1] [abc=10:=3:def=1:xyz=1] && [abc] ==> [abc=11:3:def=1:xyz=1] [abc=11:3:def=1:xyz=1] && [ghi] ==> [abc=11:3:def=1:xyz=1:ghi=1]
there's problem when numbers increase 1 digit 2 digits.
one problem
in code:
if (nispresentflag == 1) (j = 0; j < i; j++) sprintf(workbuf, "%s%s=%s:", workbuf, pdata[j][0], pdata[j][1]);
you invoking undefined behaviour writing workbuf
, passing 1 of parameters. dangerous. there's moderate chance you'll away it, 'get away' operative term — there's no guarantee work.
the overwrite problem occurs when format new number insufficient space.
working code
the code below seems work:
#include <string.h> #include <stdio.h> #include <stdlib.h> static void updatestring(char *mainstring, char toupdate[20]) { char *pdata[50][2]; char *saveptr1 = null; int = 0; int nispresentflag = 0; char workbuf1[200]; char workbuf[200]; char extra[16]; if (strlen(mainstring) > 0) strcat(mainstring, ":"); strcpy(workbuf1, mainstring); pdata[i][0] = strtok_r(workbuf1, "=", &saveptr1); pdata[i][1] = strtok_r(null, ":", &saveptr1); if (pdata[i][0]) i++; while ((pdata[i][0] = strtok_r(null, "=", &saveptr1)) != 0) { pdata[i][1] = strtok_r(null, ":", &saveptr1); i++; } (int j = 0; j < i; j++) { if (strncmp(toupdate, pdata[j][0], strlen(pdata[j][0])) == 0) { unsigned int cdrcnt = atoi(pdata[j][1]); cdrcnt += 1; pdata[j][1] = extra; sprintf(pdata[j][1], "%u", cdrcnt); nispresentflag = 1; break; } } if (nispresentflag == 1) { char *dst = workbuf; (int j = 0; j < i; j++) { int n = sprintf(dst, "%s=%s:", pdata[j][0], pdata[j][1]); /* broken if sprintf() returns -1 */ dst += n; } } else sprintf(workbuf, "%s%s=%d:", mainstring, toupdate, 1); workbuf[strlen(workbuf)-1] = '\0'; strcpy(mainstring, workbuf); } static void chkit(char *s, char *u) { printf("[%s] && [%s]", s, u); updatestring(s, u); printf(" ==> [%s]\n", s); } int main(void) { char mainstring[200] = ""; chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "xyz"); chkit(mainstring, "xyz"); chkit(mainstring, "xyz"); chkit(mainstring, "def"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "abc"); chkit(mainstring, "xyz"); chkit(mainstring, "abc"); chkit(mainstring, "ghi"); chkit(mainstring, "pqrstu"); chkit(mainstring, "i"); chkit(mainstring, "i"); chkit(mainstring, "i"); chkit(mainstring, "pqrstu"); return 0; }
it leaves out memset()
operations; null terminated string can copied on arbitrary data , long don't go looking beyond null terminator, won't have problems. variable extra
used store new number; avoids problems when number changes n n+1 digits. function sprintf()
returns number of characters wrote; used add data work buffer safely.
example output
[] && [abc] ==> [abc=1] [abc=1] && [abc] ==> [abc=2] [abc=2] && [abc] ==> [abc=3] [abc=3] && [xyz] ==> [abc=3:xyz=1] [abc=3:xyz=1] && [xyz] ==> [abc=3:xyz=2] [abc=3:xyz=2] && [xyz] ==> [abc=3:xyz=3] [abc=3:xyz=3] && [def] ==> [abc=3:xyz=3:def=1] [abc=3:xyz=3:def=1] && [abc] ==> [abc=4:xyz=3:def=1] [abc=4:xyz=3:def=1] && [abc] ==> [abc=5:xyz=3:def=1] [abc=5:xyz=3:def=1] && [abc] ==> [abc=6:xyz=3:def=1] [abc=6:xyz=3:def=1] && [abc] ==> [abc=7:xyz=3:def=1] [abc=7:xyz=3:def=1] && [abc] ==> [abc=8:xyz=3:def=1] [abc=8:xyz=3:def=1] && [abc] ==> [abc=9:xyz=3:def=1] [abc=9:xyz=3:def=1] && [abc] ==> [abc=10:xyz=3:def=1] [abc=10:xyz=3:def=1] && [xyz] ==> [abc=10:xyz=4:def=1] [abc=10:xyz=4:def=1] && [abc] ==> [abc=11:xyz=4:def=1] [abc=11:xyz=4:def=1] && [ghi] ==> [abc=11:xyz=4:def=1:ghi=1] [abc=11:xyz=4:def=1:ghi=1] && [pqrstu] ==> [abc=11:xyz=4:def=1:ghi=1:pqrstu=1] [abc=11:xyz=4:def=1:ghi=1:pqrstu=1] && [i] ==> [abc=11:xyz=4:def=1:ghi=1:pqrstu=1:i=1] [abc=11:xyz=4:def=1:ghi=1:pqrstu=1:i=1] && [i] ==> [abc=11:xyz=4:def=1:ghi=1:pqrstu=1:i=2] [abc=11:xyz=4:def=1:ghi=1:pqrstu=1:i=2] && [i] ==> [abc=11:xyz=4:def=1:ghi=1:pqrstu=1:i=3] [abc=11:xyz=4:def=1:ghi=1:pqrstu=1:i=3] && [pqrstu] ==> [abc=11:xyz=4:def=1:ghi=1:pqrstu=2:i=3]
i did basic checking valgrind
(and added dynamic memory allocation) , came clean bill of health.
note style of diagnostic printing. shows inputs , output, helpful. , encloses strings in distinctive marker (here []
) stray spaces etc can spotted more easily.
Comments
Post a Comment