Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems with a Replacing variable routine!!!

Status
Not open for further replies.

aboujouj83

IS-IT--Management
May 9, 2003
52
US
I am implementing a routine that takes a string as input and has to replace any variable in it by its value. A variable in unix starts by the dollar sign $. This routine is used in a parseLine routine for my unix shell program.

For the purpose of just testing the replacement routine, I am trying the code below:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void replaceVariables(char*);

int main (void){
char line []=&quot;/dgddg/$dfdf&quot;;
replaceVariables(line);
printf(&quot;%s\n&quot;,line);
return 0;
}

void replaceVariables(char *line){

char *temptk[32];
char tempLine[32];
char newLine[32];
int i = 0;
int j;

/* backup the line */
strcpy (tempLine, line);

/* tokenize the line using the / delimiter */
temptk = strtok(line,&quot;/&quot;);

while(temptk != NULL) {

/* check if it starts with a $ sign */
if (temptk[0] == '$')

/* check for possible variable susbstitution */
/*if (strcmp(findVar(env, temptk + 1), &quot;notfound&quot;) != 0)*/
/* here the variable is found */
{
/* replace the variable by its value */
/* FOR THE PURPOSE OF TESTING, I ALWAYS REPLACE IT BY &quot;changed&quot;*/
strcpy (temptk, &quot;changed&quot;);
}

i++;
temptk = strtok (NULL, &quot;/&quot;);
}

/* creates the new line */
strcpy (newLine, temptk[0]);

for (j = 1; j < i; j ++){
strcat (newLine, &quot;/&quot;);
printf(&quot;creating new Line/n&quot;);
strcat (newLine, temptk[j]);
}


/* deals with the case where the original line starts with a &quot;/&quot; */
if (tempLine [0] == '/'){
strcpy (line, &quot;/&quot;);
strcat (line, newLine);
}
else
strcpy (line, newLine);

}

IT IS GIVING ME A SEGMENTATION FAULT. WHAT IS THE PROBLEM? AND AM I USING THE BEST WAY TO SOLVE SUCH PROBLEM? ANY HELP IS VERY APPRECIATED.

THANKS

 
1. See TGML instructions on this forum (Process TGML link). Embrace C code with
Code:
[code]...[<slash>code]
!
2. See
Code:
line
var in your snippet (main). sizeof(line) == 13, it's char[13] only. Then you pass it to replaceVariables and push into this array any texts with strcpy etc via temptk pointer. This pointer refers to line var memory! Memory crash.
3. After line crashing you may crash newLine local var. But that italics (TGML effect)... Let's correct #2 then continue...
 
Just looking through your code quickly, (sorry, I'm in a hurry)

You are using temptk & strtok incorrectly.

Here is your code with the changes, look it over & see if it works for you:

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void replaceVariables(char*);

int main (void){
    char line []=&quot;/dgddg/$dfdf&quot;;
    replaceVariables(line);
    printf(&quot;%s\n&quot;,line);
return 0;
}

void replaceVariables(char *line){

    char *temptk[32];
    char tempLine[32];
    char newLine[32];
    int i = 0;
    int j;

    /* backup the line */
    strcpy (tempLine, line);

    /* tokenize the line using the / delimiter */
    temptk[i] = strtok(line,&quot;/&quot;);

    while(temptk[i] != NULL) {

        /* check if it starts with a $ sign */
        if (temptk[0] == '$')

            /* check for possible variable susbstitution */
             /*if (strcmp(findVar(env, temptk + 1), &quot;notfound&quot;) != 0)*/
                /* here the variable is found */
                {
                    /* replace the variable by its value */
                    /* FOR THE PURPOSE OF TESTING, I ALWAYS REPLACE IT BY &quot;changed&quot;*/
                    strcpy (temptk, &quot;changed&quot;);
                }

        i++;
        temptk = strtok (NULL, &quot;/&quot;);
    }

    /* creates the new line */
    strcpy (newLine, temptk[0]);

    for (j = 1; j < i; j ++){
        strcat (newLine, &quot;/&quot;);
        printf(&quot;creating new Line\n&quot;);
        strcat (newLine, temptk[j]);
    }


    /* deals with the case where the original line starts with a &quot;/&quot; */
    if (tempLine [0] == '/'){
        strcpy (line, &quot;/&quot;);
        strcat (line, newLine);
    }
    else
        strcpy (line, newLine);

}

Good Luck.
 
Here is another approach I wrote as a project
some time ago with no error checking to return
just the separator string(s) instead of the
tokenized string.
Maybe it will give you an idea.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define MAXMATCH 500

typedef struct p {
int nelements;
int array[MAXMATCH];
} places;

places *identify(char *,char *);
void printstarts(places *);
char **fooreturn(places *, int, char *);


int main(int argc, char **argv) {
int t;
places *yy;
char **new;
           
             yy = identify(argv[2],argv[1]);
             if (yy != NULL && yy->nelements > 0) {
                printstarts(yy);
                new = fooreturn(yy,strlen(argv[2]),argv[1]);
                for (t=0 ; t < yy->nelements ; t++) {
                     printf(&quot;%s\n&quot;, new[t]);
                }
             }
return 0;
}


places *identify(char *look, char *str) {
int y = 0, g =0;
char *tmp;
places *p = malloc(sizeof(places));

                     if (p) {
                        p->nelements = 0;
                        tmp = str;
                        while (y < strlen(str)) {
                               if ( (strncmp(tmp,look,strlen(look))) == 0) {
                                  tmp += strlen(look);
                                  p->array[g] = y;
                                  p->nelements++;
                                  y += strlen(look);
                                  g++;
                                  continue;
                               }
                               y++;
                               tmp++;
                         } 
                         return  p;
                       }
                      return NULL;
}                

       
void printstarts(places *pt) {
int p = 0;
              
              printf(&quot;%d matches\n&quot;, pt->nelements);
              while (p < pt->nelements) {
                    printf(&quot;Start of match at: %d\n&quot;, pt->array[p]);
                    p++;
              }
}
 
char **fooreturn(places *q, int num, char *str)  {
int x;
char *tmp = str;
char **rarray = malloc(num * sizeof(char *));
             
                for (x=0 ; x < q->nelements ; x++) {
                    tmp += q->array[x];
                    rarray[x] = malloc((num + 1) * sizeof(char));    
                    strncpy(rarray[x],tmp,num);
                    rarray[x][num +1] = '\0';
                    tmp = str;
                 }
return rarray;
}
 
Oops, the tgml got me, which as I look closer at your code is what happened with you also. I'll change variable 'i' to 'l'.

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void replaceVariables(char*);

int main (void){
    char line [32]=&quot;/dgddg/$dfdf&quot;;
    replaceVariables(line);
    printf(&quot;%s\n&quot;,line);
return 0;
}

void replaceVariables(char *line){

    char *temptk[32];
    char tempLine[32];
    char newLine[32];
    int l = 0;
    int j;

    /* backup the line */
    strcpy (tempLine, line);

    /* tokenize the line using the / delimiter */
    temptk[l] = strtok(line,&quot;/&quot;);

    while(temptk[l] != NULL) {

        /* check if it starts with a $ sign */
	if (temptk[l][0] == '$')

            /* check for possible variable susbstitution */
             /*if (strcmp(findVar(env, temptk + 1), &quot;notfound&quot;) != 0)*/
                /* here the variable is found */
                {
                    /* replace the variable by its value */
		    /* FOR THE PURPOSE OF TESTING, I ALWAYS REPLACE IT BY &quot;changed&quot;*/
		    temptk[l] = &quot;changed&quot;;
		}

        l++;
        temptk[l] = strtok (NULL, &quot;/&quot;);
    }

    /* creates the new line */
    strcpy (newLine, temptk[0]);

    for (j = 1; j < l; j ++){
        strcat (newLine, &quot;/&quot;);
        printf(&quot;creating new Line\n&quot;);
        strcat (newLine, temptk[j]);
    }


    /* deals with the case where the original line starts with a &quot;/&quot; */
    if (tempLine [0] == '/'){
        strcpy (line, &quot;/&quot;);
        strcat (line, newLine);
    }
    else
        strcpy (line, newLine);

}

Good Luck... again.
 
Thanks for your help! Your comments were very useful.
My working code is below. Hopefully, it will help for future reference:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void replaceVariables(char*);

int main (void){
char line []=&quot;$dfdf/abc&quot;;
replaceVariables(line);
printf(&quot;%s\n&quot;,line);
return 0;
}

void replaceVariables(char *line){

char *temptk[32];
char tempLine[32];
char newLine[32];
char tempStr[32];
int k = 0;
//int j;

/* backup the line */
strcpy (tempLine, line);

/* tokenize the line using the / delimiter */
temptk[k] = strtok(line, &quot;/&quot;);


while(temptk[k] != NULL) {
strcpy (tempStr,temptk[k]);

/* creating the new line */

/* check if it starts with a $ sign */
if (temptk[k][0] == '$')

/* check for possible variable susbstitution */
/*if (strcmp(findVar(env, temptk[k] + 1), &quot;notfound&quot;) != 0)*/
/* here the variable is found */
{
/* replace the variable by its value */
/* FOR THE PURPOSE OF TESTING, I ALWAYS REPLACE IT BY &quot;changed&quot;*/
strcpy (tempStr, &quot;changed&quot;);
}


if (k==0)
strcpy (newLine, tempStr);
else
{
strcat (newLine, &quot;/&quot;);
strcat (newLine, tempStr);
}

k++;
temptk[k] = strtok (NULL, &quot;/&quot;);
}

/* creates the new line */

/* deals with the case where the original line starts with a &quot;/&quot; */
if (tempLine [0] == '/'){
strcpy (line, &quot;/&quot;);
strcat (line, newLine);
}
else
strcpy (line, newLine);

}

ABOUJOUJ
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top