--- imach/src/imach.c 2003/06/24 12:34:15 1.90 +++ imach/src/imach.c 2003/06/25 15:30:29 1.91 @@ -1,6 +1,13 @@ -/* $Id: imach.c,v 1.90 2003/06/24 12:34:15 brouard Exp $ +/* $Id: imach.c,v 1.91 2003/06/25 15:30:29 brouard Exp $ $State: Exp $ $Log: imach.c,v $ + Revision 1.91 2003/06/25 15:30:29 brouard + * imach.c (Repository): Duplicated warning errors corrected. + (Repository): Elapsed time after each iteration is now output. It + helps to forecast when convergence will be reached. Elapsed time + is stamped in powell. We created a new html file for the graphs + concerning matrix of covariance. It has extension -cov.htm. + Revision 1.90 2003/06/24 12:34:15 brouard (Module): Some bugs corrected for windows. Also, when mle=-1 a template is output in file "or"mypar.txt with the design @@ -174,12 +181,12 @@ #define ODIRSEPARATOR '/' #endif -/* $Id: imach.c,v 1.90 2003/06/24 12:34:15 brouard Exp $ */ +/* $Id: imach.c,v 1.91 2003/06/25 15:30:29 brouard Exp $ */ /* $State: Exp $ */ char version[]="Imach version 0.96a, June 2003, INED-EUROREVES "; -char fullversion[]="$Revision: 1.90 $ $Date: 2003/06/24 12:34:15 $"; -int erreur; /* Error number */ +char fullversion[]="$Revision: 1.91 $ $Date: 2003/06/25 15:30:29 $"; +int erreur, nberr=0, nbwarn=0; /* Error number, number of errors number of warnings */ int nvar; int cptcovn=0, cptcovage=0, cptcoveff=0,cptcov; int npar=NPARMAX; @@ -211,7 +218,7 @@ char fileresilk[FILENAMELENGTH]; /* File FILE *ficresilk; FILE *ficgp,*ficresprob,*ficpop, *ficresprobcov, *ficresprobcor; FILE *ficresprobmorprev; -FILE *fichtm; /* Html File */ +FILE *fichtm, *fichtmcov; /* Html File */ FILE *ficreseij; char filerese[FILENAMELENGTH]; FILE *ficresvij; @@ -232,7 +239,15 @@ char filerest[FILENAMELENGTH]; char fileregp[FILENAMELENGTH]; char popfile[FILENAMELENGTH]; -char optionfilegnuplot[FILENAMELENGTH], optionfilehtm[FILENAMELENGTH]; +char optionfilegnuplot[FILENAMELENGTH], optionfilehtm[FILENAMELENGTH], optionfilehtmcov[FILENAMELENGTH] ; + +struct timeval start_time, end_time, curr_time, last_time, forecast_time; +struct timezone tzp; +extern int gettimeofday(); +struct tm tmg, tm, tmf, *gmtime(), *localtime(); +long time_value; +extern long time(); +char strcurr[80], strfor[80]; #define NR_END 1 #define FREE_ARG char* @@ -713,6 +728,19 @@ void linmin(double p[], double xi[], int free_vector(pcom,1,n); } +char *asc_diff_time(long time_sec, char ascdiff[]) +{ + long sec_left, days, hours, minutes; + days = (time_sec) / (60*60*24); + sec_left = (time_sec) % (60*60*24); + hours = (sec_left) / (60*60) ; + sec_left = (sec_left) %(60*60); + minutes = (sec_left) /60; + sec_left = (sec_left) % (60); + sprintf(ascdiff,"%d day(s) %d hour(s) %d minute(s) %d second(s)",days, hours, minutes, sec_left); + return ascdiff; +} + /*************** powell ************************/ void powell(double p[], double **xi, int n, double ftol, int *iter, double *fret, double (*func)(double [])) @@ -723,6 +751,8 @@ void powell(double p[], double **xi, int double del,t,*pt,*ptt,*xit; double fp,fptt; double *xits; + int niterf, itmp; + pt=vector(1,n); ptt=vector(1,n); xit=vector(1,n); @@ -733,9 +763,11 @@ void powell(double p[], double **xi, int fp=(*fret); ibig=0; del=0.0; - printf("\nPowell iter=%d -2*LL=%.12f",*iter,*fret); - fprintf(ficlog,"\nPowell iter=%d -2*LL=%.12f",*iter,*fret); - fprintf(ficrespow,"%d %.12f",*iter,*fret); + last_time=curr_time; + (void) gettimeofday(&curr_time,&tzp); + printf("\nPowell iter=%d -2*LL=%.12f %ld sec. %ld sec.",*iter,*fret, curr_time.tv_sec-last_time.tv_sec, curr_time.tv_sec-start_time.tv_sec);fflush(stdout); + fprintf(ficlog,"\nPowell iter=%d -2*LL=%.12f %ld sec. %ld sec.",*iter,*fret, curr_time.tv_sec-last_time.tv_sec, curr_time.tv_sec-start_time.tv_sec); + fprintf(ficrespow,"%d %.12f %ld",*iter,*fret,curr_time.tv_sec-start_time.tv_sec); for (i=1;i<=n;i++) { printf(" %d %.12f",i, p[i]); fprintf(ficlog," %d %.12lf",i, p[i]); @@ -743,7 +775,28 @@ void powell(double p[], double **xi, int } printf("\n"); fprintf(ficlog,"\n"); - fprintf(ficrespow,"\n"); + fprintf(ficrespow,"\n");fflush(ficrespow); + if(*iter <=3){ + tm = *localtime(&curr_time.tv_sec); + asctime_r(&tm,strcurr); + forecast_time=curr_time; + itmp = strlen(strcurr); + if(strcurr[itmp-1]=='\n') + strcurr[itmp-1]='\0'; + printf("\nConsidering the time needed for this last iteration #%d: %ld seconds,\n",*iter,curr_time.tv_sec-last_time.tv_sec); + fprintf(ficlog,"\nConsidering the time needed for this last iteration #%d: %ld seconds,\n",*iter,curr_time.tv_sec-last_time.tv_sec); + for(niterf=10;niterf<=30;niterf+=10){ + forecast_time.tv_sec=curr_time.tv_sec+(niterf-*iter)*(curr_time.tv_sec-last_time.tv_sec); + tmf = *localtime(&forecast_time.tv_sec); + asctime_r(&tmf,strfor); +/* strcpy(strfor,asctime(&tmf)); */ + itmp = strlen(strfor); + if(strfor[itmp-1]=='\n') + strfor[itmp-1]='\0'; + printf(" - if your program needs %d iterations to converge, convergence will be \n reached in %s or\n on %s (current time is %s);\n",niterf, asc_diff_time(forecast_time.tv_sec-curr_time.tv_sec,tmpout),strfor,strcurr); + fprintf(ficlog," - if your program needs %d iterations to converge, convergence will be \n reached in %s or\n on %s (current time is %s);\n",niterf, asc_diff_time(forecast_time.tv_sec-curr_time.tv_sec,tmpout),strfor,strcurr); + } + } for (i=1;i<=n;i++) { for (j=1;j<=n;j++) xit[j]=xi[j][i]; fptt=(*fret); @@ -1398,7 +1451,7 @@ double funcone( double *x) char *subdirf(char fileres[]) { - + /* Caution optionfilefiname is hidden */ strcpy(tmpout,optionfilefiname); strcat(tmpout,"/"); /* Add to the right */ strcat(tmpout,fileres); @@ -2036,6 +2089,7 @@ void concatwav(int wav[], int **dh, int wav[i]=mi; if(mi==0){ + nbwarn++; if(first==0){ printf("Warning! None valid information for:%ld line=%d (skipped) and may be others, see log file\n",num[i],i); first=1; @@ -2056,10 +2110,11 @@ void concatwav(int wav[], int **dh, int j= rint(agedc[i]*12-agev[mw[mi][i]][i]*12); if(j==0) j=1; /* Survives at least one month after exam */ else if(j<0){ + nberr++; printf("Error! Negative delay (%d to death) between waves %d and %d of individual %ld at line %d who is aged %.1f with statuses from %d to %d\n ",j,mw[mi][i],mw[mi+1][i],num[i], i,agev[mw[mi][i]][i],s[mw[mi][i]][i] ,s[mw[mi+1][i]][i]); - j=1; /* Careful Patch */ + j=1; /* Temporary Dangerous patch */ printf(" We assumed that the date of interview was correct (and not the date of death) and postponed the death %d month(s) (one stepm) after the interview.\n You MUST fix the contradiction between dates.\n",stepm); - printf("Error! Negative delay (%d to death) between waves %d and %d of individual %ld at line %d who is aged %.1f with statuses from %d to %d\n ",j,mw[mi][i],mw[mi+1][i],num[i], i,agev[mw[mi][i]][i],s[mw[mi][i]][i] ,s[mw[mi+1][i]][i]); + fprintf(ficlog,"Error! Negative delay (%d to death) between waves %d and %d of individual %ld at line %d who is aged %.1f with statuses from %d to %d\n ",j,mw[mi][i],mw[mi+1][i],num[i], i,agev[mw[mi][i]][i],s[mw[mi][i]][i] ,s[mw[mi+1][i]][i]); fprintf(ficlog," We assumed that the date of interview was correct (and not the date of death) and postponed the death %d month(s) (one stepm) after the interview.\n You MUST fix the contradiction between dates.\n",stepm); } k=k+1; @@ -2079,6 +2134,7 @@ void concatwav(int wav[], int **dh, int /* if (j<10) printf("j=%d jmin=%d num=%d ",j,jmin,i); */ /*printf("%d %lf %d %d %d\n", i,agev[mw[mi][i]][i],j,s[mw[mi][i]][i] ,s[mw[mi+1][i]][i]);*/ if(j<0){ + nberr++; printf("Error! Negative delay (%d) between waves %d and %d of individual %ld at line %d who is aged %.1f with statuses from %d to %d\n ",j,mw[mi][i],mw[mi+1][i],num[i], i,agev[mw[mi][i]][i],s[mw[mi][i]][i] ,s[mw[mi+1][i]][i]); fprintf(ficlog,"Error! Negative delay (%d) between waves %d and %d of individual %ld at line %d who is aged %.1f with statuses from %d to %d\n ",j,mw[mi][i],mw[mi+1][i],num[i], i,agev[mw[mi][i]][i],s[mw[mi][i]][i] ,s[mw[mi+1][i]][i]); } @@ -2809,9 +2865,19 @@ void varprob(char optionfilefiname[], do fprintf(fichtm,"\n
  • Computing and drawing one step probabilities with their confidence intervals

  • \n"); fprintf(fichtm,"\n"); - fprintf(fichtm,"\n
  • Computing matrix of variance-covariance of step probabilities

  • \n"); - fprintf(fichtm,"\nWe have drawn ellipsoids of confidence around the pij, pkl to understand the covariance between two incidences. They are expressed in year-1 in order to be less dependent of stepm.
    \n"); - fprintf(fichtm,"\n
    We have drawn x'cov-1x = 4 where x is the column vector (pij,pkl). It means that if pij and pkl where uncorrelated the (2X2) matrix would have been (1/(var pij), 0 , 0, 1/(var pkl)), and the confidence interval would be 2 standard deviations wide on each axis.
    When both incidences are correlated we diagonalised the inverse of the covariance matrix and made the appropriate rotation.
    \n"); + fprintf(fichtm,"\n
  • Computing matrix of variance-covariance of step probabilities

  • \n",optionfilehtmcov); + fprintf(fichtmcov,"\n

    Computing matrix of variance-covariance of step probabilities

    \n\ + file %s
    \n",optionfilehtmcov); + fprintf(fichtmcov,"\nEllipsoids of confidence centered on point (pij, pkl) are estimated\ +and drawn. It helps understanding how is the covariance between two incidences.\ + They are expressed in year-1 in order to be less dependent of stepm.
    \n"); + fprintf(fichtmcov,"\n
    Contour plot corresponding to x'cov-1x = 4 (where x is the column vector (pij,pkl)) are drawn. \ +It can be understood this way: if pij and pkl where uncorrelated the (2x2) matrix of covariance \ +would have been (1/(var pij), 0 , 0, 1/(var pkl)), and the confidence interval would be 2 \ +standard deviations wide on each axis.
    \ + Now, if both incidences are correlated (usual case) we diagonalised the inverse of the covariance matrix\ + and made the appropriate rotation to look at the uncorrelated principal directions.
    \ +To be simple, these graphs help to understand the significativity of each parameter in relation to a second other one.
    \n"); cov[1]=1; tj=cptcoveff; @@ -2993,13 +3059,13 @@ void varprob(char optionfilefiname[], do fprintf(ficgp,"\nset parametric;unset label"); fprintf(ficgp,"\nset log y;set log x; set xlabel \"p%1d%1d (year-1)\";set ylabel \"p%1d%1d (year-1)\"",k1,l1,k2,l2); fprintf(ficgp,"\nset ter png small\nset size 0.65,0.65"); - fprintf(fichtm,"\n
    Ellipsoids of confidence cov(p%1d%1d,p%1d%1d) expressed in year-1\ + fprintf(fichtmcov,"\n
    Ellipsoids of confidence cov(p%1d%1d,p%1d%1d) expressed in year-1\ :\ %s%d%1d%1d-%1d%1d.png, ",k1,l1,k2,l2,\ subdirf2(optionfilefiname,"varpijgr"), j1,k1,l1,k2,l2,\ subdirf2(optionfilefiname,"varpijgr"), j1,k1,l1,k2,l2); - fprintf(fichtm,"\n
    ",subdirf2(optionfilefiname,"varpijgr"), j1,k1,l1,k2,l2); - fprintf(fichtm,"\n
    Correlation at age %d (%.3f),",(int) age, c12); + fprintf(fichtmcov,"\n
    ",subdirf2(optionfilefiname,"varpijgr"), j1,k1,l1,k2,l2); + fprintf(fichtmcov,"\n
    Correlation at age %d (%.3f),",(int) age, c12); fprintf(ficgp,"\nset out \"%s%d%1d%1d-%1d%1d.png\"",subdirf2(optionfilefiname,"varpijgr"), j1,k1,l1,k2,l2); fprintf(ficgp,"\nset label \"%d\" at %11.3e,%11.3e center",(int) age, mu1,mu2); fprintf(ficgp,"\n# Age %d, p%1d%1d - p%1d%1d",(int) age, k1,l1,k2,l2); @@ -3008,7 +3074,7 @@ void varprob(char optionfilefiname[], do mu2,std,v21,sqrt(lc1),v22,sqrt(lc2)); }else{ first=0; - fprintf(fichtm," %d (%.3f),",(int) age, c12); + fprintf(fichtmcov," %d (%.3f),",(int) age, c12); fprintf(ficgp,"\n# Age %d, p%1d%1d - p%1d%1d",(int) age, k1,l1,k2,l2); fprintf(ficgp,"\nset label \"%d\" at %11.3e,%11.3e center",(int) age, mu1,mu2); fprintf(ficgp,"\nreplot %11.3e+ %.3f*(%11.3e*%11.3e*cos(t)+%11.3e*%11.3e*sin(t)), %11.3e +%.3f*(%11.3e*%11.3e*cos(t)+%11.3e*%11.3e*sin(t)) not",\ @@ -3031,7 +3097,8 @@ void varprob(char optionfilefiname[], do fclose(ficresprob); fclose(ficresprobcov); fclose(ficresprobcor); - /* fclose(ficgp);*/ + fflush(ficgp); + fflush(fichtmcov); } @@ -3794,6 +3861,7 @@ void prwizard(int ncovmodel, int nlstate } /* end of prwizard */ + /***********************************************/ /**************** Main Program *****************/ /***********************************************/ @@ -3857,15 +3925,10 @@ int main(int argc, char *argv[]) int lstra; long total_usecs; - struct timeval start_time, end_time, curr_time; - struct timezone tzp; - extern int gettimeofday(); - struct tm tmg, tm, *gmtime(), *localtime(); - long time_value; - extern long time(); /* gettimeofday(&start_time, (struct timezone*)0); */ /* at first time */ (void) gettimeofday(&start_time,&tzp); + curr_time=start_time; tm = *localtime(&start_time.tv_sec); tmg = *gmtime(&start_time.tv_sec); strcpy(strstart,asctime(&tm)); @@ -3886,6 +3949,8 @@ int main(int argc, char *argv[]) * printf("tim_value=%d,asctime=%s\n",time_value,strstart); */ + nberr=0; /* Number of errors and warnings */ + nbwarn=0; getcwd(pathcd, size); printf("\n%s\n%s",version,fullversion); @@ -3937,6 +4002,8 @@ int main(int argc, char *argv[]) printf("Localtime (at start):%s",strstart); fprintf(ficlog,"Localtime (at start): %s",strstart); fflush(ficlog); +/* (void) gettimeofday(&curr_time,&tzp); */ +/* printf("Elapsed time %d\n", asc_diff_time(curr_time.tv_sec-start_time.tv_sec,tmpout)); */ /* */ strcpy(fileres,"r"); @@ -4328,11 +4395,13 @@ int main(int argc, char *argv[]) s[m][i]=-1; } if((int)moisdc[i]==99 && (int)andc[i]==9999 && s[m][i]>nlstate){ + nberr++; printf("Error! Date of death (month %2d and year %4d) of individual %ld on line %d was unknown, you must set an arbitrary year of death or he/she is skipped and results are biased\n",(int)moisdc[i],(int)andc[i],num[i],i); fprintf(ficlog,"Error! Date of death (month %2d and year %4d) of individual %ld on line %d was unknown, you must set an arbitrary year of death or he/she is skipped and results are biased\n",(int)moisdc[i],(int)andc[i],num[i],i); s[m][i]=-1; } if((int)moisdc[i]==99 && (int)andc[i]!=9999 && s[m][i]>nlstate){ + nberr++; printf("Error! Month of death of individual %ld on line %d was unknown %2d, you should set it otherwise the information on the death is skipped and results are biased.\n",num[i],i,(int)moisdc[i]); fprintf(ficlog,"Error! Month of death of individual %ld on line %d was unknown %f, you should set it otherwise the information on the death is skipped and results are biased.\n",num[i],i,moisdc[i]); s[m][i]=-1; /* We prefer to skip it (and to skip it in version 0.8a1 too */ @@ -4351,6 +4420,7 @@ int main(int argc, char *argv[]) /*if(moisdc[i]==99 && andc[i]==9999) s[m][i]=-1;*/ else { if ((int)andc[i]!=9999){ + nbwarn++; printf("Warning negative age at death: %ld line:%d\n",num[i],i); fprintf(ficlog,"Warning negative age at death: %ld line:%d\n",num[i],i); agev[m][i]=-1; @@ -4387,6 +4457,7 @@ int main(int argc, char *argv[]) for (i=1; i<=imx; i++) { for(m=firstpass; (m<=lastpass); m++){ if (s[m][i] > (nlstate+ndeath)) { + nberr++; printf("Error: on wave %d of individual %d status %d > (nlstate+ndeath)=(%d+%d)=%d\n",m,i,s[m][i],nlstate, ndeath, nlstate+ndeath); fprintf(ficlog,"Error: on wave %d of individual %d status %d > (nlstate+ndeath)=(%d+%d)=%d\n",m,i,s[m][i],nlstate, ndeath, nlstate+ndeath); goto end; @@ -4469,12 +4540,24 @@ int main(int argc, char *argv[]) /* fclose(ficgp);*/ /*--------- index.htm --------*/ - strcpy(optionfilehtm,optionfilefiname); + strcpy(optionfilehtm,optionfilefiname); /* Main html file */ strcat(optionfilehtm,".htm"); if((fichtm=fopen(optionfilehtm,"w"))==NULL) { printf("Problem with %s \n",optionfilehtm), exit(0); } + strcpy(optionfilehtmcov,optionfilefiname); /* Only for matrix of covariance */ + strcat(optionfilehtmcov,"-cov.htm"); + if((fichtmcov=fopen(optionfilehtmcov,"w"))==NULL) { + printf("Problem with %s \n",optionfilehtmcov), exit(0); + } + else{ + fprintf(fichtmcov,"\nIMaCh Cov %s\n %s
    %s
    \ +
    \n\ +Title=%s
    Datafile=%s Firstpass=%d Lastpass=%d Stepm=%d Weight=%d Model=%s
    \n",\ + fileres,version,fullversion,title,datafile,firstpass,lastpass,stepm, weightopt, model); + } + fprintf(fichtm,"\nIMaCh %s\n %s
    %s
    \
    \n\ Title=%s
    Datafile=%s Firstpass=%d Lastpass=%d Stepm=%d Weight=%d Model=%s
    \n\ @@ -4485,10 +4568,9 @@ Title=%s
    Datafile=%s Firstpass=%d La - Log file of the run: %s
    \n\ - Gnuplot file name: %s
    \n\ - Date and time at start: %s\n",\ - fileres,version,fullversion,title,datafile,firstpass,lastpass,stepm, weightopt,\ - model,fileres,fileres,\ + fileres,version,fullversion,title,datafile,firstpass,lastpass,stepm, weightopt, model,\ + fileres,fileres,\ filelog,filelog,optionfilegnuplot,optionfilegnuplot,strstart); - /*fclose(fichtm);*/ fflush(fichtm); strcpy(pathr,path); @@ -5024,60 +5106,58 @@ ageminpar, agemax, s[lastpass][imx], age fflush(ficgp); - if(erreur >0){ - printf("End of Imach with error or warning %d\n",erreur); - fprintf(ficlog,"End of Imach with error or warning %d\n",erreur); + if((nberr >0) || (nbwarn>0)){ + printf("End of Imach with %d errors and/or warnings %d\n",nberr,nbwarn); + fprintf(ficlog,"End of Imach with %d errors and/or warnings %d\n",nberr,nbwarn); }else{ - printf("End of Imach\n"); - fprintf(ficlog,"End of Imach\n"); + printf("End of Imach\n"); + fprintf(ficlog,"End of Imach\n"); } printf("See log file on %s\n",filelog); - fclose(ficlog); /* gettimeofday(&end_time, (struct timezone*)0);*/ /* after time */ (void) gettimeofday(&end_time,&tzp); tm = *localtime(&end_time.tv_sec); tmg = *gmtime(&end_time.tv_sec); strcpy(strtend,asctime(&tm)); printf("Localtime at start %s\nLocaltime at end %s",strstart, strtend); - fprintf(ficlog,"Localtime at start %s\nLocal time at end %s",strstart, strtend); - /* printf("Total time used %d Sec\n", asc_time(end_time.tv_sec -start_time.tv_sec);*/ + fprintf(ficlog,"Localtime at start %s\nLocal time at end %s\n",strstart, strtend); + printf("Total time used %s\n", asc_diff_time(end_time.tv_sec -start_time.tv_sec,tmpout)); - printf("Total time was %d Sec. %d uSec.\n", end_time.tv_sec -start_time.tv_sec, end_time.tv_usec -start_time.tv_usec); - fprintf(ficlog,"Total time was %d Sec. %d uSec.\n", end_time.tv_sec -start_time.tv_sec, end_time.tv_usec -start_time.tv_usec); + printf("Total time was %d Sec.\n", end_time.tv_sec -start_time.tv_sec); + fprintf(ficlog,"Total time used %s\n", asc_diff_time(end_time.tv_sec -start_time.tv_sec,tmpout)); + fprintf(ficlog,"Total time was %d Sec.\n", end_time.tv_sec -start_time.tv_sec); /* printf("Total time was %d uSec.\n", total_usecs);*/ /* if(fileappend(fichtm,optionfilehtm)){ */ fprintf(fichtm,"
    Local time at start %s
    Local time at end %s
    ",strstart, strtend); fclose(fichtm); + fclose(fichtmcov); fclose(ficgp); + fclose(ficlog); /*------ End -----------*/ - end: -#ifdef windows - /* chdir(pathcd);*/ -#endif chdir(path); - /*system("wgnuplot graph.plt");*/ - /*system("../gp37mgw/wgnuplot graph.plt");*/ - /*system("cd ../gp37mgw");*/ - /* system("..\\gp37mgw\\wgnuplot graph.plt");*/ strcpy(plotcmd,GNUPLOTPROGRAM); strcat(plotcmd," "); strcat(plotcmd,optionfilegnuplot); printf("Starting graphs with: %s",plotcmd);fflush(stdout); - system(plotcmd); + if((outcmd=system(plotcmd)) != 0){ + printf(" Problem with gnuplot\n"); + } printf(" Wait..."); - - /*#ifdef windows*/ while (z[0] != 'q') { /* chdir(path); */ - printf("\nType e to edit output files, g to graph again, c to start again, and q for exiting: "); + printf("\nType e to edit output files, g to graph again and q for exiting: "); scanf("%s",z); - if (z[0] == 'c') system("./imach"); - else if (z[0] == 'e') system(optionfilehtm); +/* if (z[0] == 'c') system("./imach"); */ + if (z[0] == 'e') system(optionfilehtm); else if (z[0] == 'g') system(plotcmd); else if (z[0] == 'q') exit(0); } - /*#endif */ + end: + while (z[0] != 'q') { + printf("\nType q for exiting: "); + scanf("%s",z); + } }