Thread: strstr() segmentation fault help

  1. #1
    Registered User
    Join Date
    Apr 2004
    Posts
    13

    strstr() segmentation fault help

    Hi, im new here, as well as a C programming language noob.
    Also, i have a school assignment, which i dont expect it to be solved, nor a complete code, but i will need your help in understanding certain things that i completely miss.

    Given a certain ficheiro.c with the following in there(example):

    Code:
     #incluir "something.c"
    when i run my program, i expect this to return something.c
    (the name of the file prededing #incluir )
    /.file2 ficheiro.c

    i get the following errors:

    Code:
    File ficheiro.c successfully opened !!! 
    1
    Segmentation fault (core dumped)


    the following code :

    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXLINE 1024
    int main(int argc, char * argv[])
    {
      int i,j,k,n;
      char *incluir="#incluir";
      char line[MAXLINE];
      char file_name[MAXLINE];
      FILE *fp;
      fp=fopen(argv[1],"r");         
      
      if(fp==NULL)                       /* if it cant open */
        printf("File cant be opened %s\n",argv[1]);    
      else
        {                              /* if it can */
          printf("File %s successfully opened !!! \n",argv[1]);  
          
          
          while(fgets(line, MAXLINE , fp))  /* copies the first line */
    	{
    	  printf("1\n");         /* making sure it enters the loop */
    	  if(strstr(line,incluir)!= 0)	/* looks for "#incluir" in the line */		
    	    {
    	      printf("COOL it exists");
    	      
           /* in order to copy the name of the file i must first 
    	  know until where i will copy */
    	      j=0; n=0;                
    	      while( n<=2 )
    		{
    		  if(line[j] == '\"')
    		    n++; 
    		  j++;
    		}
    	      /* now int j has the position of where ' " ' is */
    
    	      
    	      /* the file *.c has in it -> #incluir "something.h" <-
    		 the first ' " ', occurs at the position 9, so i
    		 will start copying from 9 to j */
    	      
    	      for(i=9; k=0, i<j , i++; k++)		
    		{
    		  file_name[k]=line[i];
    		}
    	      file_name[k+1]='\0';    /* converting it into a string so 
    					 i can read it later */
    	      printf("%s \n", file_name);   
    	    }       
    	  else
    	    {
    	      printf("%s\n", line);  /* for debugging purposes */
    	      printf("%s\n", incluir);
    	      printf("OOPS it doesn't");	
    	    }
    	}
        }
      return 0;
    }


    when it goes into if(strstr(line,incluir)!= 0) , thats where it goes Segmentation fault, and i know it has to do with memory and for example, it happens when in an array[10], its assigned 100 chars/ints/whatever .
    Please help.
    Last edited by Rpog; 04-14-2004 at 08:47 AM. Reason: didnt present in code

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    strstr isn't the problem. The problem is in this loop:
    Code:
    j=0; n=0;                
    while( n<=2 )
    {
      if(line[j] == '\"')
        n++; 
      j++;
    }
    If you print out the value of j in this loop you'll discover that it is much larger than you think. That alone probably doesn't cause the segmentation fault because you aren't writing to memory (even though looking at memory you don't own is still undefined behavior). But when you get to this loop:
    Code:
    for(i=9; k=0, i<j , i++; k++)		
    {
      file_name[k]=line[i];
    }
    j is the stopping condition for the loop, so k will definitely be higher than you want, and you will also be writing to those memory locations that you don't own. That's causing your segmentation fault.

    How do you fix it? Simple. Change two things. The first loop should test for two double quotations, not 3 as you are actually testing for:
    Code:
    j=0; n=0;                
    while( n<2 )
    {
      if(line[j] == '\"')
        n++; 
      j++;
    }
    And the for loop is ill-formed. It is still legal, but your semicolons are misplaced, causing the loop to go longer than it should. It should be:
    Code:
    for(i=9, k=0; i<j; i++, k++) 
    {
      file_name[k]=line[i];
    }
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Apr 2004
    Posts
    13
    thx for your help, i already converted the loop for, and it corrected one error, however, i didnt quite catch the 3 double quotation part.
    It still goes into segmentation fault.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >It still goes into segmentation fault.
    This is the code I'm using to test with. It runs properly with the example file you gave.
    Code:
    #include <stdio.h>
    #include <string.h>
    #define MAXLINE 1024
    int main(int argc, char * argv[])
    {
      int i,j,k,n;
      char *incluir="#incluir";
      char line[MAXLINE];
      char file_name[MAXLINE];
      FILE *fp;
      fp=fopen(argv[1],"r"); 
    
      if(fp==NULL) /* if it cant open */
        printf("File cant open %s\n",argv[1]); 
      else
      { /* if it can */
        printf("File %s successfully opened !!! \n",argv[1]); 
    
    
        while(fgets(line, MAXLINE , fp)) /* copies the first line */
        {
          printf("1\n"); /* making sure it enters the cicle */
          if(strstr(line,incluir)!= 0) /* looks for "#incluir" in the line */ 
          {
            printf("COOL it exists");
    
            /* in order to copy the name of the file i must first 
            know until where i will copy */
            j=0; n=0; 
            while( n<2 )
            {
              if(line[j] == '\"')
                n++; 
              j++;
            }
            /* now int j has the position of where ' " ' is */
    
    
            /* the file *.c has in it -> #incluir "something.h" <-
            the first ' " ', occurs at the position 9, so i
            will start copying from 9 to j */
    
            for(i=9, k=0; i<j; i++, k++) 
            {
              file_name[k]=line[i];
            }
            file_name[k+1]='\0'; /* converting it into a string so 
                                 i can read it later */
            printf("%s \n", file_name); 
          } 
          else
          {
            printf("%s\n", line); /* for debugging purposes */
            printf("%s\n", incluir);
            printf("OOPS it doesn't"); 
          }
        }
      }
      return 0;
    }
    Can you post the code that you're using along with the exact contents of the file you're opening? Also mention what your OS and compiler are.
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Apr 2004
    Posts
    13

    Thumbs up :) :)

    thanks a lot, i should have done something wrong, i copied and pasted your code, and it worked.
    Thanks again.


    P.S : by the way, the OS was Solaris, and the compiler was gcc.

  6. #6
    Registered User
    Join Date
    Apr 2004
    Posts
    13
    This has nothing to do with my previous work, but its from a friend of mine, which has the same doubt as i do.
    When i compile the following code, it returns the following errors, in Solaris OS for Sparc and the compiler is gcc:

    patresi.c: In function `reconhece':
    patresi.c:13: `linha' undeclared (first use in this function)
    patresi.c:13: (Each undeclared identifier is reported only once
    patresi.c:13: for each function it appears in.)
    patresi.c:14: warning: implicit declaration of function `fazincluir'
    patresi.c:16: warning: implicit declaration of function `fazesquecer'
    patresi.c:18: warning: implicit declaration of function `fazdefinir'
    patresi.c: In function `analisa':
    patresi.c:26: `linha' undeclared (first use in this function)

    dont care about the warnings, our doubt is about the undeclared stuff, why are they undeclared?, even with us declaring extern variables.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    void apanhalinha (FILE *ficheiro){
      char linha[1024]; 
      (fgets(linha,1024,ficheiro));
    }
    
    void reconhece (char *mcr){
      char incluir[] = "#incluir ";
      char esquecer[] = "#esquecer ";
      char definir[] = "#definir ";
      if ((strncmp(incluir, linha, 9)) > 0)
        fazincluir(linha);
      if ((strncmp(esquecer, linha, 10)) > 0)
        fazesquecer(linha);
      if ((strncmp(definir, linha, 9)) > 0)
        fazdefinir(linha);}
    
    
    void analisa(FILE *ficheiro){
      int c;
      while((c=fgetc(ficheiro)) != EOF)
        if(c == '#')
          apanhalinha(ficheiro);
      reconhece(linha);
     }
    
    
    int main(int argc, char* argv[]){
      FILE *pre;
      pre = fopen (argv[1], "r");
      if (pre == NULL)
        printf("Erro: Impossivel abrir ficheiro a pre-processar\n");
      else analisa(pre);
      return 0;
    }

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >dont care about the warnings
    As you wish...

    >why are they undeclared?
    Well, let's take a look:

    >patresi.c: In function `reconhece':
    >patresi.c:13: `linha' undeclared
    If you look at function reconhece, you'll see that no variable called linha is declared. There is a variable called linha declared in the function apanhalinha, but that doesn't mean that reconhece can see it. The same goes for analisa.

    >even with us declaring extern variables
    I don't see any extern variables in the code you posted. If you want linha to be a global variable, then make it so:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    char linha[1024];
    
    void apanhalinha (FILE *ficheiro){ 
      (fgets(linha,1024,ficheiro));
    }
    
    void reconhece (char *mcr){
      char incluir[] = "#incluir ";
      char esquecer[] = "#esquecer ";
      char definir[] = "#definir ";
      if ((strncmp(incluir, linha, 9)) > 0)
        fazincluir(linha);
      if ((strncmp(esquecer, linha, 10)) > 0)
        fazesquecer(linha);
      if ((strncmp(definir, linha, 9)) > 0)
        fazdefinir(linha);}
    
    
    void analisa(FILE *ficheiro){
      int c;
      while((c=fgetc(ficheiro)) != EOF)
        if(c == '#')
          apanhalinha(ficheiro);
      reconhece(linha);
     }
    
    int main(int argc, char* argv[]){
      FILE *pre;
      pre = fopen (argv[1], "r");
      if (pre == NULL)
        printf("Erro: Impossivel abrir ficheiro a pre-processar\n");
      else analisa(pre);
      return 0;
    }
    Otherwise, you'll need to declare it in main and pass it as an argument to other functions.
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Apr 2004
    Posts
    13
    thanks again

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quick Ques on String Manipulation
    By ckuttruff in forum C Programming
    Replies: 8
    Last Post: 06-22-2008, 09:32 PM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM