Hello all,

I have a problem with a function I wrote.

I wrote a main() that takes from current library a *.c file (that the user gives by the argv[1]) and make a copy of itself but without the comments and saves it as *.c1, so after this operation we will have 2 files, the first one is *.c (didn't change anything in it), the other is *.c1 (*.c without comments).

The other part is a function that takes this *.c1 file pointer and makes another file (third one) *.c2 which is exactly as *.c1 file, but all the #include <file.h> statements will be replaced with the contents of the file.h's .

The main() with its functions is:

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

enum status {OUT , IN_STRING , LEFT_SLASH , IN_COMMENT , RIGHT_STAR , IN_CPP_COM};

/*functions declarations*/
void chk_correct_file_arg(char *s);
void chk_no_arg(int num);
void includes_extractor(FILE *c1_fp , char *c1_file_name ,int c1_file_str_len );

int main(int argc , char **argv)
{
	FILE *c_fp , *c1_fp;	/* fd -> *.c ; c1_fp -> *.c1 */
	int ch;
	int state = OUT;	
	int c1_file_string_len = strlen(argv[1])+2; /*num of chars in name.c +1 for name.c1*/
	char *c1_file_name;
	
	chk_correct_file_arg(argv[1]);
	chk_no_arg(argc);
	
	c1_file_name=(char *) malloc ((c1_file_string_len)*sizeof(char)); 
	
	strcpy(c1_file_name , argv[1]);	
	c1_file_name[c1_file_string_len-1] = '\0'; 
	c1_file_name[c1_file_string_len-2] = '1';
	
	if( !(c_fp = fopen (argv[1],"r") ) )
	{
	 fprintf(stderr,"cannot open source file !\n");
	 exit(0);
	}

	if( !(c1_fp = fopen (c1_file_name,"w+") ) )
	{
	 fprintf(stderr,"cannot open destination file !\n");
	 exit(0);
	}

	
	
	ch=fgetc(c_fp);
	while (!feof(c_fp)){	

		switch (state)
		{
     			case OUT:
				if (ch=='/')
				{
				 state = LEFT_SLASH;
				}
			    	else
				{
				 fputc(ch,c1_fp);
				 if (ch=='\"')
				   state = IN_STRING;
				}			  
				break; /*OUT*/

			case LEFT_SLASH:
				if(ch=='*')
				{
				 state = IN_COMMENT;
				}
				else if (ch=='/')
				{
				 state = IN_CPP_COM;
				}
				else
				{
				 fputc('/',c1_fp);
				 fputc(ch,c1_fp);
				 state = OUT;
				}
				break; /*LEFT_SLASH*/
						 
			case IN_COMMENT:
				if(ch=='*')
				{
				 state = RIGHT_STAR;
				}
				break; /*IN_COMMENT*/
				
			case IN_CPP_COM:
				if(ch=='\n')
				{
				 state = OUT;
				 fputc('\n',c1_fp);			
				}
				break; /*IN_CPP_COM*/
	
			case RIGHT_STAR:
				if(ch=='/')
				{
				 state = OUT;
				}
				else if (ch!= '*')
				{
				 state = IN_COMMENT;
				}
				break; /*RIGHT_STAR*/

			case IN_STRING:
				if(ch=='\"')
				{
				 state = OUT;
				}
				fputc(ch,c1_fp);
				break; /*IN_STRING*/


		} /*switch*/
	ch=fgetc(c_fp);
} /*while*/
	fclose(c_fp);
	fclose(c1_fp);
	return 0; /*dummy*/

includes_extractor(c1_fp , c1_file_name ,c1_file_string_len); /*extract all headers*/

} /*main()*/


/* This func validate that the data entered into argv[1] refer to a file type of *.c */
void chk_correct_file_arg(char *s)
{
 int arg_len;
 arg_len = strlen(s);
 if( !( (s[arg_len] == '\0') && (s[arg_len-1] == 'c') && (s[arg_len-2] == '.') ))
{
 printf("\n%s is an incorrect file name type !!\n\n",s);
 exit(0);
}		 
} /*chk_correct_file_arg*/

/*This func validate that # of argv organs are exact 2*/
void chk_no_arg(int num_arg)
{
 if (num_arg > 2)
 {
  printf("\nToo many arguments !\n\n Program will now terminate !");
  exit(0);	
 }	

 if (num_arg == 1)
 {
  printf("\nMissing argument !\n\n Program will now terminate !");
  exit(0);
 }
}/*chk_no_arg*/

The function that makes another file (*.c2) is:

/*This func runs *.c1 file, and replace every include file with its content*/
void includes_extractor(FILE *c1_fp , char *c1_file_name ,int c1_file_str_len )
{

	int i=0,header_file_len=0;
	FILE *c2_fp , *header_fp;
	char *c2_file_name, ch, inc_name[]="include",*header_name;
	char inc_chk[8]; /*[8] are 7 for "include" +1 for null*/

	header_name=(char *) malloc ((header_file_len)*sizeof(char)); 

	c2_file_name=(char *) malloc ((c1_file_str_len)*sizeof(char)); 
	c2_file_name[c1_file_str_len-1] = '\0'; 
	c2_file_name[c1_file_str_len-2] = '2';

/*Open source & destination files + ERR check */

	if( !(c1_fp = fopen (c1_file_name,"r") ) )
	{
	 fprintf(stderr,"\ncannot open *.c1 file !\n");
	 exit(0);
	}
	
	if( !(c2_fp = fopen (c2_file_name,"w+") ) )
	{
	 fprintf(stderr,"\ncannot open *.c2 file !\n");
	 exit(0);
	}

/*next code lines are copy char by char from c1 to c2,
  but if meet header file, copy its content */

	ch=fgetc(c1_fp);
	while (!feof(c1_fp))
	{
		if (ch == '#') /*potential #include occur*/
		{
	         fgets(inc_chk, 8, c1_fp); /*8 places for "include" + null*/
		 if(strcmp(inc_chk,inc_name)==0) /*means we are in include case*/
		 {
		  ch=fgetc(c1_fp);
		  while(ch==' ') /*stop when head with a '<' or '"'*/
		  {
		   ch=fgetc(c1_fp);
		  } /*while(2)*/
		  ch=fgetc(c1_fp); /*start read header file name*/
		  while((ch!='"') || (ch!='>')) /*until we get end of header name*/
		  {
		   header_name[i] = ch;
		   i++;
		   ch=fgetc(c1_fp);
		  }/*while(3)*/
		  header_name[i]='\0'; /*close the header_name array*/
		  header_file_len=strlen(header_name); 		  
		  if( !(header_fp = fopen (header_name,"r") ) ) /*open *.h for read + ERR chk*/
		  {
	           fprintf(stderr,"cannot open header file !\n");
	 	   exit(0);
	          }
		  while (!feof(header_fp)) /*copy header file content to *.c2 file*/
		  {
		   ch=fgetc(header_fp);
		   fputc(ch,c2_fp);
		  }/*while(4)*/
		  fclose(header_fp);
		 }
                }/*frst if*/
		else
		{
		 fputc(ch,c2_fp);
		}
	 ch=fgetc(c1_fp); 
	}/*while(1)*/
fclose(c1_fp);
fclose(c2_fp);
}/*includes_extractor*/

Everything compile perfectly, but the function does not create the *.c2 file, only the *.c1 file is created...
Many Thanks !!

Run the program with your compiler's debugger and find out why *.c2 is not being created. Possibly the function is not even being called.

Since includes can be nested -- that is, one include file can contain other include files -- you will need the function that processes includes to be recursive. Afterall, there is no limit to how deeply includes can be made.

Run the program with your compiler's debugger and find out why *.c2 is not being created. Possibly the function is not even being called.

Since includes can be nested -- that is, one include file can contain other include files -- you will need the function that processes includes to be recursive. Afterall, there is no limit to how deeply includes can be made.

I don't need to deal with nested includes.
I remake my program, and now the file created but still empty.. also I get segmentation fault... I can't point the problem.

The func:

void includes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len )
{

	int i=0,header_file_len=0;
	FILE *c2_fp , *header_fp;
	char *c2_file_name, ch, inc_name[]="include",*header_name;
	char inc_chk[8]; /*[8] are 7 for "include" +1 for null*/

	header_name=(char *) malloc ((header_file_len)*sizeof(char)); 
	c2_file_name=(char *) malloc ((c1_file_str_len)*sizeof(char)); 

	strcpy(c2_file_name , c1_file_name); /*<<<<<<<<<<< I CHANGED HERE*/


	c2_file_name[c1_file_str_len-1] = '\0'; 
	c2_file_name[c1_file_str_len-2] = '2';

/*Open source & destination files + ERR check */

	if( !(c1_fp = fopen (c1_file_name,"r") ) )
	{
	 fprintf(stderr,"\ncannot open *.c1 file !\n");
	 exit(0);
	}
	
	if( !(c2_fp = fopen (c2_file_name,"w+") ) )
	{
	 fprintf(stderr,"\ncannot open *.c2 file !\n");
	 exit(0);
	}

/*next code lines are copy char by char from c1 to c2,
  but if meet header file, copy its content */

	ch=fgetc(c1_fp);
	while (!feof(c1_fp))
	{
		if (ch == '#') /*potential #include occur*/
		{
	         fgets(inc_chk, 8, c1_fp); /*8 places for "include" + null*/
		 if(strcmp(inc_chk,inc_name)==0) /*means we are in include case*/
		 {
		  ch=fgetc(c1_fp);
		  while(ch==' ') /*stop when head with a '<' or '"'*/
		  {
		   ch=fgetc(c1_fp);
		  } /*while(2)*/
		  ch=fgetc(c1_fp); /*start read header file name*/
		  while((ch!='"') || (ch!='>')) /*until we get end of header name*/
		  {
		   header_name[i] = ch;
		   i++;
		   ch=fgetc(c1_fp);
		  }/*while(3)*/
		  header_name[i]='\0'; /*close the header_name array*/
		  header_file_len=strlen(header_name); 		  
		  if( !(header_fp = fopen (header_name,"r") ) ) /*open *.h for read + ERR chk*/
		  {
	           fprintf(stderr,"cannot open header file !\n");
	 	   exit(0);
	          }
		  while (!feof(header_fp)) /*copy header file content to *.c2 file*/
		  {
		   ch=fgetc(header_fp);
		   fputc(ch,c2_fp);
		  }/*while(4)*/
		  fclose(header_fp);
		 }
                }/*frst if*/
		else
		{
		 fputc(ch,c2_fp);
		}
	 ch=fgetc(c1_fp); 
	}/*while(1)*/
fclose(c1_fp);
fclose(c2_fp);
free (header_name);
free (c2_file_name);
}/*includes_extractor*/

The main():

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

enum status {OUT , IN_STRING , LEFT_SLASH , IN_COMMENT , RIGHT_STAR , IN_CPP_COM};

/*functions declarations*/
void chk_correct_file_arg(char *s);
void chk_no_arg(int num);
void includes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len );

int main(int argc , char **argv)
{
	FILE *c_fp , *c1_fp;	/* fd -> *.c ; c1_fp -> *.c1 */
	int ch;
	int state = OUT;	
	int c1_file_string_len = strlen(argv[1])+2; /*num of chars in name.c +1 for name.c1*/
	char *c1_file_name;
	
	chk_correct_file_arg(argv[1]);
	chk_no_arg(argc);
	
	c1_file_name=(char *) malloc ((c1_file_string_len)*sizeof(char)); 
	
	strcpy(c1_file_name , argv[1]);	
	c1_file_name[c1_file_string_len-1] = '\0'; 
	c1_file_name[c1_file_string_len-2] = '1';
	
	if( !(c_fp = fopen (argv[1],"r") ) )
	{
	 fprintf(stderr,"cannot open source file !\n");
	 exit(0);
	}

	if( !(c1_fp = fopen (c1_file_name,"w+") ) )
	{
	 fprintf(stderr,"cannot open destination file !\n");
	 exit(0);
	}

	
	
	ch=fgetc(c_fp);
	while (!feof(c_fp)){	

		switch (state)
		{
     			case OUT:
				if (ch=='/')
				{
				 state = LEFT_SLASH;
				}
			    	else
				{
				 fputc(ch,c1_fp);
				 if (ch=='\"')
				   state = IN_STRING;
				}			  
				break; /*OUT*/

			case LEFT_SLASH:
				if(ch=='*')
				{
				 state = IN_COMMENT;
				}
				else if (ch=='/')
				{
				 state = IN_CPP_COM;
				}
				else
				{
				 fputc('/',c1_fp);
				 fputc(ch,c1_fp);
				 state = OUT;
				}
				break; /*LEFT_SLASH*/
						 
			case IN_COMMENT:
				if(ch=='*')
				{
				 state = RIGHT_STAR;
				}
				break; /*IN_COMMENT*/
				
			case IN_CPP_COM:
				if(ch=='\n')
				{
				 state = OUT;
				 fputc('\n',c1_fp);			
				}
				break; /*IN_CPP_COM*/
	
			case RIGHT_STAR:
				if(ch=='/')
				{
				 state = OUT;
				}
				else if (ch!= '*')
				{
				 state = IN_COMMENT;
				}
				break; /*RIGHT_STAR*/

			case IN_STRING:
				if(ch=='\"')
				{
				 state = OUT;
				}
				fputc(ch,c1_fp);
				break; /*IN_STRING*/


		} /*switch*/
	ch=fgetc(c_fp);
} /*while*/
	fclose(c_fp);
	fclose(c1_fp);

	includes_extractor(c1_fp, c1_file_name ,c1_file_string_len); 
	free(c1_file_name);/*extract all headers*/	
return 0; /*dummy*/



} /*main()*/


/* This func validate that the data entered into argv[1] refer to a file type of *.c */
void chk_correct_file_arg(char *s)
{
 int arg_len;
 arg_len = strlen(s);
 if( !( (s[arg_len] == '\0') && (s[arg_len-1] == 'c') && (s[arg_len-2] == '.') ))
{
 printf("\n%s is an incorrect file name type !!\n\n",s);
 exit(0);
}		 
} /*chk_correct_file_arg*/

/*This func validate that # of argv organs are exact 2*/
void chk_no_arg(int num_arg)
{
 if (num_arg > 2)
 {
  printf("\nToo many arguments !\n\n Program will now terminate !");
  exit(0);	
 }	

 if (num_arg == 1)
 {
  printf("\nMissing argument !\n\n Program will now terminate !");
  exit(0);
 }
}/*chk_no_arg*/

I just need an hint to finish this urgent assignment...:icon_cry:

Thanks !

Edited 5 Years Ago by Adami: n/a

Since you can't use the debugger, I'd suggest outputting key variables after key statements in your code. Like after an open, after an input, after an important calculation. Do the variables contain valid information?

Since you can't use the debugger, I'd suggest outputting key variables after key statements in your code. Like after an open, after an input, after an important calculation. Do the variables contain valid information?

Hi,

I search again and ran it 'on paper' and maybe the problem seems to be with:

header_file_len=strlen(header_name);

that written in a wrong place in this function ?

Another thing is that for the next header file, the 'i' index still be with previous value, and if I zero it after array done, the program shows crazy things on screen when compiling it.
If not please give me a clue, because this assignment kills me...

Edited 5 Years Ago by Adami: n/a

Since you can't use the debugger, I'd suggest outputting key variables after key statements in your code. Like after an open, after an input, after an important calculation. Do the variables contain valid information?

I changed minor things, but still does not working (segmentation fault).
I tried several printings like you have told me, but nothing... please please please tell me what I did wrong .

Thank you...

The Function:

void includes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len )
{
	int i;
	int header_file_len=0;
	FILE *c2_fp , *header_fp;
	char ch, *c2_file_name, *header_name;
	char inc_name[]="include"; 
	char inc_chk[INCLUDE_LEN+1]; /*+1 for null*/

	header_name=(char *) malloc ((header_file_len)*sizeof(char)); 

	/* making the c2 file name */

	c2_file_name=(char *) malloc ((c1_file_str_len)*sizeof(char)); 
	strcpy(c2_file_name , c1_file_name); 
	c2_file_name[c1_file_str_len-1] = '\0'; 
	c2_file_name[c1_file_str_len-2] = '2';

/*Open source & destination files + ERR check */

	if( !(c1_fp = fopen (c1_file_name,"r") ) )
	{
	 fprintf(stderr,"\ncannot open *.c1 file !\n");
	 exit(0);
	}
	
	if( !(c2_fp = fopen (c2_file_name,"w+") ) )
	{
	 fprintf(stderr,"\ncannot open *.c2 file !\n");
	 exit(0);
	}

/*next code lines are copy char by char from c1 to c2,
  but if meet header file, copy its content */

	ch=fgetc(c1_fp);
	while (!feof(c1_fp))
	{
		i=0;	/*zero i */	
		if (ch == '#') /*potential #include case*/
		{
	         fgets(inc_chk, INCLUDE_LEN+1, c1_fp); /*8 places for "include" + null*/
		 if(strcmp(inc_chk,inc_name)==0) /*case #include*/
		 {
		  ch=fgetc(c1_fp);
		  while(ch==' ') /* stop when head with a '<' or '"' */
		  {
		   ch=fgetc(c1_fp);
		  } /*while(2)*/
		  ch=fgetc(c1_fp); /*start read header file name*/
		  while((ch!='"') || (ch!='>')) /*until we get the end of header name*/
		  {
		   header_name[i] = ch;
		   i++;
		   ch=fgetc(c1_fp);
		  }/*while(3)*/
		  header_name[i]='\0';
		   /*close the header_name array*/
		  header_file_len=strlen(header_name)+1; /*+1 for NULL */	  
		  if( !(header_fp = fopen (header_name,"r") ) ) /*open *.h for read + ERR chk*/
		  {
	           fprintf(stderr,"cannot open header file !\n");
	 	   exit(0);
	          }
		  while (!feof(header_fp)) /*copy header file content to *.c2 file*/
		  {
		   ch=fgetc(header_fp);
		   fputc(ch,c2_fp);
		  }/*while(4)*/
		  fclose(header_fp);
		 }
                }/*frst if*/
		else
		{
		 fputc(ch,c2_fp);
		}
	 ch=fgetc(c1_fp); 
	}/*while(1)*/
fclose(c1_fp);
fclose(c2_fp);
free (header_name);
free (c2_file_name);
}/*includes_extractor*/

The main():

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define INCLUDE_LEN 7 /* "include" length */
enum status {OUT , IN_STRING , LEFT_SLASH , IN_COMMENT , RIGHT_STAR , IN_CPP_COM};

/*functions declarations*/
void chk_correct_file_arg(char *s);
void chk_no_arg(int num);
void includes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len );

int main(int argc , char **argv)
{
	FILE *c_fp , *c1_fp;	/* fd -> *.c ; c1_fp -> *.c1 */
	int ch;
	int state = OUT;	
	int c1_file_string_len = strlen(argv[1])+2; /*num of chars in name.c +1 for name.c1*/
	char *c1_file_name;
	
	chk_correct_file_arg(argv[1]);
	chk_no_arg(argc);
	
	c1_file_name=(char *) malloc ((c1_file_string_len)*sizeof(char)); 
	
	strcpy(c1_file_name , argv[1]);	
	c1_file_name[c1_file_string_len-1] = '\0'; 
	c1_file_name[c1_file_string_len-2] = '1';
	
	if( !(c_fp = fopen (argv[1],"r") ) )
	{
	 fprintf(stderr,"cannot open source file !\n");
	 exit(0);
	}

	if( !(c1_fp = fopen (c1_file_name,"w+") ) )
	{
	 fprintf(stderr,"cannot open destination file !\n");
	 exit(0);
	}

	ch=fgetc(c_fp);
	while (!feof(c_fp)){	

		switch (state)
		{
     			case OUT:
				if (ch=='/')
				{
				 state = LEFT_SLASH;
				}
			    	else
				{
				 fputc(ch,c1_fp);
				 if (ch=='\"')
				   state = IN_STRING;
				}			  
				break; /*OUT*/

			case LEFT_SLASH:
				if(ch=='*')
				{
				 state = IN_COMMENT;
				}
				else if (ch=='/')
				{
				 state = IN_CPP_COM;
				}
				else
				{
				 fputc('/',c1_fp);
				 fputc(ch,c1_fp);
				 state = OUT;
				}
				break; /*LEFT_SLASH*/
						 
			case IN_COMMENT:
				if(ch=='*')
				{
				 state = RIGHT_STAR;
				}
				break; /*IN_COMMENT*/
				
			case IN_CPP_COM:
				if(ch=='\n')
				{
				 state = OUT;
				 fputc('\n',c1_fp);			
				}
				break; /*IN_CPP_COM*/
	
			case RIGHT_STAR:
				if(ch=='/')
				{
				 state = OUT;
				}
				else if (ch!= '*')
				{
				 state = IN_COMMENT;
				}
				break; /*RIGHT_STAR*/

			case IN_STRING:
				if(ch=='\"')
				{
				 state = OUT;
				}
				fputc(ch,c1_fp);
				break; /*IN_STRING*/


		} /*switch*/
	ch=fgetc(c_fp);
} /*while*/
	fclose(c_fp);
	fclose(c1_fp);

	includes_extractor(c1_fp, c1_file_name ,c1_file_string_len); 
	free(c1_file_name);
return 0; /*dummy*/



} /*main()*/


/* This func validate that the data entered into argv[1] refer to a file type of *.c */
void chk_correct_file_arg(char *s)
{
 int arg_len;
 arg_len = strlen(s);
 if( !( (s[arg_len] == '\0') && (s[arg_len-1] == 'c') && (s[arg_len-2] == '.') ))
{
 printf("\n%s is an incorrect file name type !!\n\n",s);
 exit(0);
}		 
} /*chk_correct_file_arg*/

/*This func validate that # of argv organs are exact 2*/
void chk_no_arg(int num_arg)
{
 if (num_arg > 2)
 {
  printf("\nToo many arguments !\n\n Program will now terminate !");
  exit(0);	
 }	

 if (num_arg == 1)
 {
  printf("\nMissing argument !\n\n Program will now terminate !");
  exit(0);
 }
}/*chk_no_arg*/

Edited 5 Years Ago by Adami: Better code wrapping

I can't allocation for a zero

int header_file_len=0;

and then

header_name=(char *) malloc ((header_file_len)*sizeof(char));

The current problem is that the problem now is that I got 1 warning reg. to the non-initialized header_file_len variable (I deleted the '=0'), and by running it, the program stuck..

I can't allocation for a zero

int header_file_len=0;

and then

header_name=(char *) malloc ((header_file_len)*sizeof(char));

What's the value of header_file_len?
Then what's the value of header_file_len * sizeof(char)?
Therefore, how much space is being malloc ed?
Is that enough to be useful?

Edited 5 Years Ago by WaltP: n/a

What's the value of header_file_len?
Then what's the value of header_file_len * sizeof(char)?
Therefore, how much space is being malloc ed?
Is that enough to be useful?

Value of header_file_len is strlen(header_name)+1 /*+1 for NULL.*/

Therefore it should be:

int header_file_len=strlen(header_name)+1;

header_name=(char *) malloc ((header_file_len)*sizeof(char));

But it still wont help because compiler says: "warning: ‘header_name’ is used uninitialized in this function".

It didn't much help...

Edited 5 Years Ago by Adami: n/a

Your compiler is right. So why don't you initialize the damned thing. Line 1 of the code snippet you posted won't worfk if header_name hasn't been initialized to something before that line is executed.

Your compiler is right. So why don't you initialize the damned thing. Line 1 of the code snippet you posted won't worfk if header_name hasn't been initialized to something before that line is executed.

So as you say, if my function goes like following, it should not work either, because I cant use malloc for header_name that use itself ?

Can you fix those lines and explain me what was wrong ?

void includes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len )
{
	int i;
	FILE *c2_fp , *header_fp;
	char ch, *c2_file_name, *header_name;
	char inc_name[]="include"; 
	char inc_chk[INCLUDE_LEN+1]; /*INCLUDE_LEN is defined | +1 for null*/

	header_name=(char *) malloc ((strlen(header_name)+1)*sizeof(char)); 
	
	/* making the c2 file name */

	c2_file_name=(char *) malloc ((c1_file_str_len)*sizeof(char)); 
	strcpy(c2_file_name , c1_file_name); 
	c2_file_name[c1_file_str_len-1] = '\0'; 
	c2_file_name[c1_file_str_len-2] = '2';

/*Open source & destination files + ERR check */

	if( !(c1_fp = fopen (c1_file_name,"r") ) )
	{
	 fprintf(stderr,"\ncannot open *.c1 file !\n");
	 exit(0);
	}
	
	if( !(c2_fp = fopen (c2_file_name,"w+") ) )
	{
	 fprintf(stderr,"\ncannot open *.c2 file !\n");
	 exit(0);
	}

/*next code lines are copy char by char from c1 to c2,
  but if meet header file, copy its content */

	ch=fgetc(c1_fp);
	while (!feof(c1_fp))
	{
		i=0;	/*zero i */	
		if (ch == '#') /*potential #include case*/
		{
	         fgets(inc_chk, INCLUDE_LEN+1, c1_fp); /*8 places for "include" + null*/
		 if(strcmp(inc_chk,inc_name)==0) /*case #include*/
		 {
		  ch=fgetc(c1_fp);
		  while(ch==' ') /* stop when head with a '<' or '"' */
		  {
		   ch=fgetc(c1_fp);
		  } /*while(2)*/
		  
		  ch=fgetc(c1_fp); /*start read header file name*/

		  while((ch!='"') || (ch!='>')) /*until we get the end of header name*/
		  {
		   header_name[i] = ch;
		   i++;
		   ch=fgetc(c1_fp);
		  }/*while(3)*/
		  header_name[i]='\0';  /*close the header_name array*/

		  if( !(header_fp = fopen (header_name,"r") ) ) /*open *.h for read + ERR chk*/
		  {
	           fprintf(stderr,"cannot open header file !\n");
	 	   exit(0);
	          }
		  while (!feof(header_fp)) /*copy header file content to *.c2 file*/
		  {
		   ch=fgetc(header_fp);
		   fputc(ch,c2_fp);
		  }/*while(4)*/
		  fclose(header_fp);
		 }
                }/*frst if*/
		else
		{
		 fputc(ch,c2_fp);
		}
	 ch=fgetc(c1_fp); 
	}/*while(1)*/
fclose(c1_fp);
fclose(c2_fp);
free (header_name);
free (c2_file_name);
}

>>header_name=(char *) malloc ((strlen(header_name)+1)*sizeof(char));

You are not thinking -- use your head for something other than a hat rack. variable header_name is nothing more than an uninitialized pointer which just points to some random location. It is not a null-terminated string, so why are you calling strlen() on it? That makes as much sense as trying to put a tire on the bumper of a car.

If you want that function to work you will have to rearrange its logic. The lines of the program have to be in the order that they are to be executed.

header_name=(char ) malloc ((strlen(header_name)+1)sizeof(char));

You are not thinking -- use your head for something other than a hat rack. variable header_name is nothing more than an uninitialized pointer which just points to some random location. It is not a null-terminated string, so why are you calling strlen() on it? That makes as much sense as trying to put a tire on the bumper of a car.

If you want that function to work you will have to rearrange its logic. The lines of the program have to be in the order that they are to be executed.

I tried this(following code) and it still gives me Segmentation fault.. but now there is no malloc... how it can be ?

void includes_extractor(FILE *c1_fp, char *c1_file_name ,int c1_file_str_len )
{
    int i=0;
    FILE *c2_fp , *header_fp;
    char ch, *c2_file_name, header_name[80];
    char inc_name[]="include"; 
    char inc_chk[INCLUDE_LEN+1]; /*INCLUDE_LEN is defined | +1 for null*/

    /* making the c2 file name */

    c2_file_name=(char *) malloc ((c1_file_str_len)*sizeof(char)); 
    strcpy(c2_file_name , c1_file_name); 
    c2_file_name[c1_file_str_len-1] = '\0'; 
    c2_file_name[c1_file_str_len-2] = '2';

/*Open source & destination files + ERR check */

    if( !(c1_fp = fopen (c1_file_name,"r") ) )
    {
     fprintf(stderr,"\ncannot open *.c1 file !\n");
     exit(0);
    }

    if( !(c2_fp = fopen (c2_file_name,"w+") ) )
    {
     fprintf(stderr,"\ncannot open *.c2 file !\n");
     exit(0);
    }

/*next code lines are copy char by char from c1 to c2,
  but if meet header file, copy its content */

    ch=fgetc(c1_fp);
    while (!feof(c1_fp))
    {
        i=0;    /*zero i */ 
        if (ch == '#') /*potential #include case*/
        {
             fgets(inc_chk, INCLUDE_LEN+1, c1_fp); /*8 places for "include" + null*/
         if(strcmp(inc_chk,inc_name)==0) /*case #include*/
         {
          ch=fgetc(c1_fp);
          while(ch==' ') /* stop when head with a '<' or '"' */
          {
           ch=fgetc(c1_fp);
          } /*while(2)*/

          ch=fgetc(c1_fp); /*start read header file name*/

          while((ch!='"') || (ch!='>')) /*until we get the end of header name*/
          {
           header_name[i] = ch;
           i++;
           ch=fgetc(c1_fp);
          }/*while(3)*/
          header_name[i]='\0';  /*close the header_name array*/


          if( !(header_fp = fopen (header_name,"r") ) ) /*open *.h for read + ERR chk*/
          {
               fprintf(stderr,"cannot open header file !\n");
           exit(0);
              }
          while (!feof(header_fp)) /*copy header file content to *.c2 file*/
          {
           ch=fgetc(header_fp);
           fputc(ch,c2_fp);
          }/*while(4)*/
          fclose(header_fp);
         }
                }/*frst if*/
        else
        {
         fputc(ch,c2_fp);
        }
     ch=fgetc(c1_fp); 
    }/*while(1)*/
fclose(c1_fp);
fclose(c2_fp);

free (c2_file_name);
}

Edited 3 Years Ago by Reverend Jim: Fixed formatting

You are going to have to learn how to use your compiler's debugger instead of asking us to be your debugger. If you're using *nix you have a program called dbg that will take the core file and tell you where the problem is. If you are in MS-Windows then use the compiler's debugger to single step each line of your program until you find out where and what the problem is.

You are going to have to learn how to use your compiler's debugger instead of asking us to be your debugger. If you're using *nix you have a program called dbg that will take the core file and tell you where the problem is. If you are in MS-Windows then use the compiler's debugger to single step each line of your program until you find out where and what the problem is.

I already use debugging prior to my last response.
The compiler says: "Segmentation fault" I googled it and found out that it probably because of illegal memory allocation, but I am not using malloc other than *.c2 file creation, and this file been created.

The problem is that I get no text inside *.c2 file for some unknown reason.
I wish I could use debugger to figure out what cause it, but I can't...

Therefore I'm asking you to point me the problem so I could solve it, I'm not lazy, it's just that I can't debug while I get "Segmentation fault"..

Can you give me a hint to find the failure ?

Thanks !!

segment fault can be caused by lots of different things, which may or may not be related to malloc(). For example if you try to copy a string into a character array and the string has more characters than the array can hold.

char file_name[5];
strcpy(file_name,"Hello Here, how are you?"); // Seg fault here

or yuu call strlen() on an uninitiaized array

char file_name[5];
int len  = strlen(file_name); // seg fault here

>>it's just that I can't debug while I get "Segmentation fault"..
Sure you can -- the debugger will stop at the place that caused the seg fault. Put break point just before that line, when the debugger stops you can check the values of local variables.

Edited 5 Years Ago by Ancient Dragon: n/a

segment fault can be caused by lots of different things, which may or may not be related to malloc(). For example if you try to copy a string into a character array and the string has more characters than the array can hold.

char file_name[5];
strcpy(file_name,"Hello Here, how are you?"); // Seg fault here

or yuu call strlen() on an uninitiaized array

char file_name[5];
int len  = strlen(file_name); // seg fault here

>>it's just that I can't debug while I get "Segmentation fault"..
Sure you can -- the debugger will stop at the place that caused the seg fault. Put break point just before that line, when the debugger stops you can check the values of local variables.

Where I can find this debugger ? I searched for a good source for download & help , but couldn't find... can you upload the debugger into here ?

Are you working on *nix or MS-Windows? Both VC++ 2010 (as well as earlier version) and Code::Blocks come with excellent debuggers. g++ on *nix has gdb. I don't do a lot of coding on *nix but I suppose Emax and others also have debuggers.

You don't have to download anything, the debuggers are installed when you install the compilers and IDEs.

This article has been dead for over six months. Start a new discussion instead.