0

The new verison compiled with no errors on my linux box. I get these runtime errors though:
when using the bigger input files:

ubuntu@ubuntu-laptop:~/Documents$ ./test desc.txt data.txt
Dml Error: at line 1
Dml error: Missing ; at line 2
ubuntu@ubuntu-laptop:~/Documents$

And with the smaller files from the original post:

ubuntu@ubuntu-laptop:~/Documents$ ./test desc.txt data.txt
Dml Error xxx at line 4
ubuntu@ubuntu-laptop:~/Documents$

I hope those errors help you.

0

The new verison compiled with no errors on my linux box. I get these runtime errors though:
when using the bigger input files:

ubuntu@ubuntu-laptop:~/Documents$ ./test desc.txt data.txt
Dml Error: at line 1
Dml error: Missing ; at line 2
ubuntu@ubuntu-laptop:~/Documents$

And with the smaller files from the original post:

ubuntu@ubuntu-laptop:~/Documents$ ./test desc.txt data.txt
Dml Error xxx at line 4
ubuntu@ubuntu-laptop:~/Documents$

I hope those errors help you.

no dude this will not help me.
the descrition file systax is quite strict.

e.g should begin with a

begin
mean if 1st line of the file is blank line it will fail.

sililarly every line should end with a semicolon and no space after the semicolon.

3rd thing column names should of single word.

make a proper dml file.
in case of dml error the code is exiting with the error code it is not going for the data file for reading.

Thanks
DP

0

That program has a considerable number of errors, bugs, buffer overruns, and memory leaks. I was finally able to get it to read the first file, after correcting all those many problems. (using VC++ 2008 Express on Vista).

0

ustrtok() is broken pretty badly. memory leaks, using uninitialized char pointers, and the second parameter should be char**, not char*

0

ustrtok() is broken pretty badly. memory leaks, using uninitialized char pointers, and the second parameter should be char**, not char*

//prototype is
char * ustrtok(char *base_string,char *next_str,char *delim);

no its char*.

function works like:

if base_string="a|b|c|d";
next_str=NULL;
delim="|"

after 1st call
=========
return is "b|c|d" which need to assigned to base_str for the next calls. and so on.
next_str=a;

Advantage of it over strtok is
========================

suppose we have base string:"a|||b|c"

strtok return 3 strings a , b and c it cant handle null values.

whereas ustrtok returns..
a,null,null,b,c.

it works fine.

but for memory leakage and all.guide me a bit about it please.so that i can design good codes.

Thanks
DP

0

Hello Everyone ,

After a lot of effort i am able to find the bug in the code.The corrected code is posted here.

the change in the code is marked with
CC-1 and CC-2.
Its working fine in LINUX machine now lets see it for solaris machine tomorrow ,lets c how it behaves on solaris.

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

#define FIXED 1
#define DELIMETED 2
#define MIXED 3


typedef struct dml_s
{
char **col_headers;
char **column_delim;
int *col_datatype;
int *col_len;
int col_cnt;
int record_length;
int file_type;          //file type can be fixed,delimeted or max len with delimeters
}dml;


void display_intro();
dml* extract_dml_info(char*,dml*);
int str_wc(char *);
int str_semicl(char *);
int pow_user(int,int);
void display_dml_info(struct dml_s *record);
void read_fixed(char *filename,int *size,char **header,int col_cnt,int record_len);
void read_delimeted(char *filename,char **delmimeter,char **header,int col_cnt);
char * ustrtok(char *base_string,char *next_str,char *delim);

int main(int argc,char *argv[])
{

if(argc!=3)
{
display_intro();
return;
}


dml *record;
record=(dml*)malloc(sizeof(dml));
record=extract_dml_info(argv[1],record);
if(record==NULL) exit(1);

display_dml_info(record);


if(record->file_type==DELIMETED)
{

read_delimeted(argv[2],record->column_delim,record->col_headers,record->col_cnt);
}


/*
else if(record->file_type=FIXED)
{
read_fixed(argv[2],record->col_len,record->col_headers,record->col_cnt,record->record_length);
}

else if(record->file_type=MIXED)
{
printf("\n\nCONSTRUCTION ON PROGRESS FOR DELIMTED FILE WITH LENGTH\n");
return;
}
*/

return 0;
}





/********************THIS FUNCTION EXTRACTS INFORMATION FROM THE
*********************DML FILE AND RETURNS A STRUCTRUE***********/

dml* extract_dml_info(char *dmlfile,dml *record)
{
char buffer[100];       //IT BUFFERS ONE LINE AT A TIME FORM THE FILE
char **line;            //ALL THE LINES FROM THE FILE STORED IN LINE ARRAY
char **col_desc;        //STORES THE COLUMN DESCRIPTIONS
char *temp,*token;
FILE *fp;
int i,j;

fp=fopen(dmlfile,"r");
if(fp==NULL)
{
printf("Can't read from file: \"%s\"\n",dmlfile);
perror("Error");
exit(1);
}


line=(char**)malloc(2000*sizeof(char*));

fgets(buffer,100,fp);
i=0;
while(!feof(fp))
{
if(buffer[strlen(buffer)-1]=='\n')
buffer[strlen(buffer)-1]='\0';
line[i]=(char*)malloc(strlen(buffer)+1);
strcpy(line[i],buffer);
i++;
fgets(buffer,100,fp);
}

record->col_cnt=i-2;                    //Getting the column count from the dml file

/*-----------CC -1 -------------*/
record->col_headers=(char**)calloc(record->col_cnt+1,sizeof(char*));
col_desc=(char**)calloc(record->col_cnt+1,sizeof(char*));


//EARLIER IT WAS

//record->col_headers=(char**)malloc(100,sizeof(char*));
//col_desc=(char**)malloc(100,sizeof(char*));

/*-----------CC -1 -------------*/

/****************DML VALIDATION***************************************
The following validation taken place
1)DML starts with a 'begin' flag and end with 'end;'
2)Every statement ends with a semicolon except the begin
3)no semicolon should encounter inside
4)each line should consist of 2 words (a)column name (b)column desc
*********************************************************************/

if(strcmp(line[0],"begin")!=0)
{
printf("Dml Error: at line 1\n");
}

int k=0;
int w_count,semicl_flag;
for(j=1;j<i;j++)
{
k=strlen(line[j]);


if(line[j][k-1]!=';')
{
printf("Dml error: Missing ; at line %d\n",j+1);
return NULL;
}
if((strchr(line[j],';'))!=NULL && line[j][k-1]!=';' )
{
printf("Dml error: at line %d\n",j+1);
return NULL;
}


w_count=str_wc(line[j]);
if( w_count != 2 && w_count != 3 && j!=i-1 )
{
printf("Dml Error xxx at line %d\n",j);
return NULL;
}

semicl_flag=str_semicl(line[j]);
if(semicl_flag==-1)
{
printf("Dml Error yyy at line %d\n",j);
return NULL;
}
else if(semicl_flag==-2)
{
printf("Dml Error zzz at line %d\n",j);
return NULL;
}
}

if(strcmp(line[i-1],"end;")!=0)
{
printf("Dml Error: at line %d\n",i);
return NULL;
}

/****************END DML VALIDATION***********************/


for(j=0;j<record->col_cnt;j++)
{
token=(char*)malloc(strlen(line[j])+1);
token=strtok(line[j+1]," ");
if(token==NULL)
{
token="\0";
return NULL;
}
record->col_headers[j]=(char*)malloc(strlen(token)+1);
strcpy(record->col_headers[j],token);
token=strtok(NULL,"\n");
col_desc[j]=(char*)malloc(strlen(token)+1);
if(token!=NULL)
strcpy(col_desc[j],token);
else
{
printf("Incorrect DML at line %d for %s\n",j+1,record->col_headers[j]);
return NULL;
}

}



/****************DETERMINE THE DATATYPE OF THE COLUMNS*********/
char *del;
record->col_datatype=(int*)malloc(2*i*sizeof(int));
int flag;
for(j=0;j<record->col_cnt;j++)
{
del=strstr(col_desc[j],"string");
if(del==NULL)
{
record->col_datatype[j]=1;
del='\0';
}
else
record->col_datatype[j]=0;
}
/*****************************************************************/


int count_fixed=0;
int count_del=0;
char *temp_del_fst;
char *temp_del_lst;
int tempv;

/****************CC--2**************/

record->column_delim=(char**)calloc((record->col_cnt+1),sizeof(char*));

//EARLIER IT WAS record->column_delim=(char**)malloc(10*sizeof(char*));
/***************CC--2**************/

for(j=0;j<record->col_cnt;j++)
{
temp_del_fst=strchr(col_desc[j],'"');
temp_del_lst=strrchr(col_desc[j],'"');
if(temp_del_fst==NULL && temp_del_lst==NULL)
{
count_fixed++;
record->column_delim[j]=(char*)malloc(2);
record->column_delim[j]="\0";
}
else if(temp_del_fst!=NULL && temp_del_lst!=NULL && temp_del_lst!=temp_del_fst)
{
count_del++;
tempv=temp_del_lst-temp_del_fst;
record->column_delim[j]=(char*)malloc(temp_del_lst-temp_del_fst);
strncpy(record->column_delim[j],temp_del_fst+1,temp_del_lst-temp_del_fst-1);
record->column_delim[j][tempv-1]='\0';
}
else if(temp_del_fst!=NULL && temp_del_lst!=NULL && temp_del_lst==temp_del_fst)
{
printf("DML Error :at line %d ,inproper description\n",j+1);
record->column_delim[j]="\0";
return  NULL;
}
}



//printf("count fixed:%d and count del :%d \n",count_fixed,count_del);
/***********/

record->record_length=0;
char *c_len;
if(count_fixed==record->col_cnt && count_del==0)
{
 record->file_type=FIXED;
 record->col_len=(int *)malloc(record->col_cnt*sizeof(int));
 for(j=0;j<record->col_cnt;j++)
 {
temp_del_fst=strchr(col_desc[j],'(');
temp_del_lst=strrchr(col_desc[j],')');
  if(temp_del_fst==NULL && temp_del_lst==NULL)
    {
     printf("Dml Error..( ) missing in column description\n");
    }
    tempv=temp_del_lst-temp_del_fst;

        c_len=(char*)malloc(10*sizeof(char));
    strncpy(c_len,temp_del_fst+1,temp_del_lst-temp_del_fst-1);

        int len=strlen(c_len);

        record->col_len[j]=atoi(c_len);
        record->record_length=record->record_length+record->col_len[j];
       // printf("length:%d\tclen:%s\tlen:%d\t j=%d\n",record->col_len[j],c_len,tempv,j);

  }

        //printf("record length is :%d\n",record->record_length);

}


/**********/
else if(count_fixed==0 && count_del==record->col_cnt)
{
record->file_type=DELIMETED;

  if(strcmp(record->column_delim[record->col_cnt-1],"\\n")!=0)
  {
    printf("DML error,in the last field '\\n' missing\n");
   return NULL;
  }
}
else
{
record->file_type=-1;
printf("DML error,Unable to determine the file type\n");
return NULL;
}

return record;
}


/******A function to get the word count of a string*******/

int str_wc(char *str)
{
int limit = strlen(str);
    int i, change = 1, words = 0;
    for(i = 0; i < limit; ++i)
    {
        if(!isspace(str[i]))
        {
            if(change)
            {
                ++words;
                change = 0;
            }
        }
        else
        {
            change = 1;
        }
            }

  return words;
}

/*************************************************************/

/*********A fucntion to check semicolon occurs in between the line***/

int str_semicl(char *str)
{
int limit = strlen(str);
int i,flag=0;

    for(i = 0; i < limit; ++i)
    {
        if(i < limit-1 && str[i]==';' )
        {
                 flag=-1;
        }

        else if( str[limit-1]==';' && isspace(str[limit-2]) )
        {
                flag=-2;
        }
        else if( str[limit-1]==';' && !(isspace(str[limit-2])))
        {
                flag=0;
        }

        else
                flag=0;

   }

  return flag;
}

/************************************************************/

/******CALCULATION POWER****************/
int pow_user(base,exp)
{
int i;
int pow=1;
for(i=0;i<exp;i++)
{
pow=pow*base;
}
return pow;
}
/****************************************/


/******IT'S A FUNCTION SIMILAR TO STRTOK BUT CAN HANDLE NULL VALUES******/
/******THIS FUNCTION SPILTS A STRING INTO TWO STRINGS W.R.T A TOKEN******/

char * ustrtok(char *base_string,char *next_str,char *delim)
{
char *str2;
str2=(char*)malloc(100);
if(base_string==NULL && strlen(base_string)<1)
{
next_str=NULL;
return NULL;
}
int len=strlen(base_string);
char *temp;
temp=(char*)malloc(100);

temp=strstr(base_string,delim);
if(temp==NULL)
{
strcpy(next_str,base_string);
next_str[strlen(next_str)]='\0';
return NULL;
}
else
{
int sub_len=temp-base_string;
str2=(char*)malloc(100);
strncpy(str2,base_string,sub_len);
str2[strlen(str2)]='\0';
strcpy(next_str,str2);
return (temp+strlen(delim));
}
}



/******************THIS FUNCTION DISPLAYS THE DML DESCRIPTION****************/


void display_dml_info(dml *record)
{

int i,j;
if(record==NULL)return;
printf("=========================\n");
printf("NO OF COLUMNS:%d\n",record->col_cnt);
printf("RECORD LENGTH:%d\n",record->record_length);
printf("FILE TYPE :\"%d\"\n",record->file_type);
printf("=========================\n");

for(j=0;j<record->col_cnt;j++)
{
printf("===COLUMN %d===\n\n",j+1);
printf("HEADER:\"%s\"\n",record->col_headers[j]);
printf("DATATYPE:\"%d\"\n",record->col_datatype[j] );
if(record->file_type==DELIMETED)printf("DELIMETER:\"%s\" DELIM LENGTH:%d\n",record->column_delim[j],strlen(record->column_delim[j]));
if(record->file_type==FIXED )printf("LENGTH:%d\n",record->col_len[j]);
}
printf("=========================\n\n");
}

/***************************************************************************************/




void read_delimeted(char *filename,char **column_delim,char **col_headers,int col_cnt)
{
FILE *data_file;
char buffer[20000];
char *ext_line=NULL;
char *temp=NULL;
char **fields=NULL;
int i,j;


data_file=fopen(filename,"r");
if(data_file==NULL)
{
printf("can't open file\n");
return;
}


j=1;
fgets(buffer,2000,data_file);
while(!feof(data_file))
{
i=0;

if(buffer[strlen(buffer)-1]=='\n')
buffer[strlen(buffer)-1]='\0';
if(strlen(buffer)==0)
goto nextline;
ext_line=(char*)malloc(strlen(buffer)+1);
if(ext_line==NULL)
{
printf("NUll Record Found\n");
}
strcpy(ext_line,buffer);
printf("\nRecord %d:\n",j);
printf("=========\n");

fields=(char**)malloc(col_cnt*sizeof(char*));
char *next_str;
temp=(char*)malloc(strlen(buffer)+1);
next_str=(char*)malloc(strlen(buffer)+1);
next_str=ustrtok(ext_line,temp,column_delim[0]);



while(i<col_cnt)
{
if(next_str==NULL)
next_str="\0";
if(ext_line==NULL)
ext_line="\0";
if(temp==NULL)
temp="\0";


fields[i]=(char*)malloc(strlen(temp));
strcpy(fields[i],temp);

fprintf(stdout,"%s:\"%s\"\n",col_headers[i],fields[i]);
ext_line=next_str;
temp=(char*)malloc(100*sizeof(char));
if(i==col_cnt-1)
{
column_delim[i+1]=column_delim[i];
}
next_str=ustrtok(ext_line,temp,column_delim[i+1]);


if(i==col_cnt-2)
{
if(ext_line==NULL)
ext_line="\0";
strcpy(temp,ext_line);
}

if(i==col_cnt-1 && strlen(ext_line)>0)
{
printf("\n\nError:Incomplete field at end of record.\n");
printf("Leftover bytes :\"%s\"\n",ext_line);
printf("Either (1) The metadata does not accurately describe the data,\n");
printf("    or (2) The data has somehow been corrupted.\n");
}
i++;
}
j++;
nextline:
fgets(buffer,2000,data_file);

}
fclose(data_file);
}



void display_intro()
{
 printf("\n mdump: Version 1.0\n\n");
 printf(" Copyright (c) 2009, Deepak Panigrahy.  All rights reserved.\n\n");
 printf(" Purpose: This program is a simple utility that display\n");
 printf("          the source file as per the Record format.\n\n");

 printf(" Usage:   mdump <Dml FileName> <Data FileName>\n\n");

 printf("          Use -h option for additional help.\n");
}
0

That program has a considerable number of errors, bugs, buffer overruns, and memory leaks. I was finally able to get it to read the first file, after correcting all those many problems. (using VC++ 2008 Express on Vista).

Hello Ancient Dragon,
Can you share your optimized code to this forum with tips and changes as comment.

And also i want to learn how to handle memory leak and buffer overflows.

Thanks,
DP

0

Here is the function again

char * ustrtok(char *base_string,char *next_str,char *delim)
{
char *str2;
str2=(char*)malloc(100);
if(base_string==NULL && strlen(base_string)<1)
{
next_str=NULL;
return NULL;
}
int len=strlen(base_string);
char *temp;
temp=(char*)malloc(100);

temp=strstr(base_string,delim);
if(temp==NULL)
{
strcpy(next_str,base_string);
next_str[strlen(next_str)]='\0';
return NULL;
}
else
{
int sub_len=temp-base_string;
str2=(char*)malloc(100);
strncpy(str2,base_string,sub_len);
str2[strlen(str2)]='\0';
strcpy(next_str,str2);
return (temp+strlen(delim));
}
}

line 5: That line will cause a crash when base_string is NULL because the second part of that statement will call strlen() with a NULL pointer. Need to use the || operator, not &&.

line 7: that does nothing but set the local copy of the pointer to NULL. When the program returns that pointer disappears, and nothing at all happens to the pointer in the calling function. And even if it did work (which it doesn't) it would cause memory leaks in the calling function. This is one reason I said that pointer needs to be char** instead of char*.

line 14: memory leak because it discards the memory allocated in the previous line.

line 18: unnecessary and can be deleted because the previous line strcpy() will null-terminated the string.

line 24: another memory leak. It was already allocated on line 2.

line 28: another memory leak -- what happens to the memory allocated on line 24???

And in the places where this function is called, I don't see where the memory for that second parameter is ever free()'ed.

0

Here is the function again

char * ustrtok(char *base_string,char *next_str,char *delim)
{
char *str2;
str2=(char*)malloc(100);
if(base_string==NULL && strlen(base_string)<1)
{
next_str=NULL;
return NULL;
}
int len=strlen(base_string);
char *temp;
temp=(char*)malloc(100);

temp=strstr(base_string,delim);
if(temp==NULL)
{
strcpy(next_str,base_string);
next_str[strlen(next_str)]='\0';
return NULL;
}
else
{
int sub_len=temp-base_string;
str2=(char*)malloc(100);
strncpy(str2,base_string,sub_len);
str2[strlen(str2)]='\0';
strcpy(next_str,str2);
return (temp+strlen(delim));
}
}

line 5: That line will cause a crash when base_string is NULL because the second part of that statement will call strlen() with a NULL pointer. Need to use the || operator, not &&.

line 7: that does nothing but set the local copy of the pointer to NULL. When the program returns that pointer disappears, and nothing at all happens to the pointer in the calling function. And even if it did work (which it doesn't) it would cause memory leaks in the calling function. This is one reason I said that pointer needs to be char** instead of char*.

line 14: memory leak because it discards the memory allocated in the previous line.

line 18: unnecessary and can be deleted because the previous line strcpy() will null-terminated the string.

line 24: another memory leak. It was already allocated on line 2.

line 28: another memory leak -- what happens to the memory allocated on line 24???

And in the places where this function is called, I don't see where the memory for that second parameter is ever free()'ed.

AGREE: line 5: That line will cause a crash when base_string is NULL because the second part of that statement will call strlen() with a NULL pointer. Need to use the || operator, not &&.

Don't Agree: line 7: that does nothing but set the local copy of the pointer to NULL. When the program returns that pointer disappears, and nothing at all happens to the pointer in the calling function. And even if it did work (which it doesn't) it would cause memory leaks in the calling function. This is one reason I said that pointer needs to be char** instead of char*.

Reason: I think is this case we are not allocating any memory just it points to null.i mean it removes the value of next string by pointing to a null location.


Don't Agree: line 14: memory leak because it discards the memory allocated in the previous line.

Reason:As we are using strcpy() we should allocate memory to the variable.

AGREE: line 18: unnecessary and can be deleted because the previous line strcpy() will null-terminated the string.

AGREE: line 24: another memory leak. It was already allocated on line 2.

Don't Agree: line 28: another memory leak -- what happens to the memory allocated on line 24???

Reason:i cant understand this thing,because it returns new address to he calling function.Its the way the function works.

AGREE: And in the places where this function is called, I don't see where the memory for that second parameter is ever free()'ed.

now i modified the function and it works fine.But i am not able to free the memory in the calling function it show bus error when i try to free it. My Code is attached below.

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


char* ustrtok(char*,char*,char*);

int main()
{

char *base_string;
char *next_str;
char *delim;
char *return1;

delim=(char*)calloc(10,sizeof(char));
strcpy(delim,"|");
base_string=(char*)calloc(100,sizeof(char));
strcpy(base_string,"a|b|c|d|e");
return1= (char*)malloc(strlen(base_string));
next_str=(char*)malloc(strlen(base_string));

return1=ustrtok(base_string,next_str,delim);
while(return1!=NULL)
{
printf("return:\"%s\"\n",return1);
printf("base_string:\"%s\"\n",base_string);
printf("next_str:\"%s\"\n",next_str);
base_string=return1;
//if(return1!=NULL) free(return1);          /*****PROBLEM SECTION-1****************/
//if(next_str!=NULL) free(next_str);	    /*****PROBLEM SECTION-2****************/
return1= (char*)malloc(strlen(base_string));
next_str=(char*)malloc(strlen(base_string));
return1=ustrtok(base_string,next_str,delim);
}

return 0;
}


char * ustrtok(char *base_string,char *next_str,char *delim)   
{								
char *temp_string;                                             
			                                       
if(base_string==NULL || strlen(base_string)<1)		//*************CHANGE-1****************//       
{							       
next_str=NULL;                                                 
return NULL;                                                   
}                                                              
int len=strlen(base_string);                                   
char *temp;                                                    
temp=(char*)calloc(len+1,sizeof(char));			//*************CHANGE-2****************//                       
temp=strstr(base_string,delim);	                               
if(temp==NULL)                                                 
{                                                              
strcpy(next_str,base_string);                                  
return NULL;                                                   
}                                                              
else                                                           
{                                                              
int sub_len=temp-base_string;                                  
temp_string=(char*)calloc(sub_len+1,sizeof(char));     //*************CHANGE-3****************//    
strncpy(temp_string,base_string,sub_len);                      
temp_string[strlen(temp_string)]='\0';                         
strcpy(next_str,temp_string);                                  
return (temp+strlen(delim));                                   
}                                                              
}

Its running as expected.Still i am getting warnings , Can i get suggestion on supressing these warnings.

sdetlab01:/export/home/dpani/cprograms/mdump> gcc -o ustrtok ustrtok.c -m64
ustrtok.c: In function `main':
ustrtok.c:14: warning: cast to pointer from integer of different size
ustrtok.c:16: warning: cast to pointer from integer of different size
ustrtok.c:18: warning: cast to pointer from integer of different size
ustrtok.c:19: warning: cast to pointer from integer of different size
ustrtok.c:30: warning: cast to pointer from integer of different size
ustrtok.c:31: warning: cast to pointer from integer of different size
ustrtok.c: In function `ustrtok':
ustrtok.c:53: warning: cast to pointer from integer of different size
ustrtok.c:63: warning: cast to pointer from integer of different size
sdetlab01:/export/home/dpani/cprograms/mdump> ustrtok

0

you are getting that seg fault because
line 51: allocate memory to temp
line 52: toss the memory away and reset pointer to somewhere in base_string or NULL
line 65: returns a pointer to the pointer returned by line 52 + the length of char* delim, which could result in an out-of-bounds error. This final pointer can not be free'ed because it doesn't point to the same address that was returned by calloc() or malloc(). So the memory allocated on line 51 is unusable.

0

you are getting that seg fault because
line 51: allocate memory to temp
line 52: toss the memory away and reset pointer to somewhere in base_string or NULL
line 65: returns a pointer to the pointer returned by line 52 + the length of char* delim, which could result in an out-of-bounds error. This final pointer can not be free'ed because it doesn't point to the same address that was returned by calloc() or malloc(). So the memory allocated on line 51 is unusable.

1)Now i got the problem.But i Cant get how to modify the code to prevent memory leak.Please advice how to modify the code.

2)Another thing in the main function , how to free the memory allocated.i cant do it.

3)Somehow my code is working very fine but still while compilation i get these warnings.please look into this.

sdetlab01:/export/home/dpani/cprograms/mdump> gcc -o ustrtok ustrtok.c -m64
ustrtok.c: In function `main':
ustrtok.c:14: warning: cast to pointer from integer of different size
ustrtok.c:16: warning: cast to pointer from integer of different size
ustrtok.c:18: warning: cast to pointer from integer of different size
ustrtok.c:19: warning: cast to pointer from integer of different size
ustrtok.c:30: warning: cast to pointer from integer of different size
ustrtok.c:31: warning: cast to pointer from integer of different size
ustrtok.c: In function `ustrtok':
ustrtok.c:53: warning: cast to pointer from integer of different size
ustrtok.c:63: warning: cast to pointer from integer of different size
sdetlab01:/export/home/dpani/cprograms/mdump> ustrtok

0

I have not been able to duplicate those warnings with my compiler.

I don't know why strtok() will not work for your program. Here is an example of its use

char iobuf[] = "Hello World";
char *ptr = strchr(iobuf, " ");
while( ptr != NULL)
{
     printf("%s\n", ptr);
     ptr = strchr( NULL, " ");
}

Note that you pass a pointer to a char array the first time, and NULL thereafter.

0

I have not been able to duplicate those warnings with my compiler.

I don't know why strtok() will not work for your program. Here is an example of its use

char iobuf[] = "Hello World";
char *ptr = strchr(iobuf, " ");
while( ptr != NULL)
{
     printf("%s\n", ptr);
     ptr = strchr( NULL, " ");
}

Note that you pass a pointer to a char array the first time, and NULL thereafter.

I think u have written strchr() instead of strtok(). Its fine.
strtok() is working but i dont need this for my purpose my requirement is different.

Limitations of strtok()

1)It cant handle NULL values in between.
its logic is ...it replaces each delimeter by '\0'

suppose
string="a|c|||f"

strtok will return 3 fields ..a , c ,f
but i need
a,c,null,null,f (null indicates blank sting "")

thats y i replaced strtok() by ustrtok()

Anyways what about freeing memory in that main program.i can free memory over there.

0

I'm late to this thread and haven't really been following it.

suppose
string="a|c|||f"

strtok will return 3 fields ..a , c ,f
but i need
a,c,null,null,f (null indicates blank sting "")

But this 'empty fields' bit reminded me of a snippet or two I'd done a while ago. FWIW.

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.