在C中找不到错误 - “分段错误”

时间:2011-02-04 23:07:38

标签: c segmentation-fault

我写了这个函数,但无法解决给我“分段错误”的问题。

感谢您的帮助!

/*This function extract all header files in a *.c1 file*/

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]; /* we can assume line length 80 chars MAX*/
    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));
    if (c2_file_name == NULL)
    {
     printf("Out of memory !\n");
     exit(0);
    } 

    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);    
}

5 个答案:

答案 0 :(得分:4)

此代码似乎包含许多错误,但对我来说最明显的是

while((ch!='"') || (ch!='>')) /*until we get the end of header name*/

我会说每个角色都与'"'的{​​{1}} 不同...或者你知道一个角色可以与两者相等吗? ; - )

答案 1 :(得分:2)

我会在黑暗中拍摄并猜测c1_file_str_len参数是来自strlen()函数调用的结果,该调用没有考虑终止NULL字符。您对strcpy的呼叫可能(会?)然后失败。

如果没有,也许您可​​以在这里提供更多帮助?试过调试?这段错误发生在哪一行?

答案 2 :(得分:2)

valgrind下运行您的程序。

答案 3 :(得分:2)

变化:

while((ch!='"') || (ch!='>'))

为:

while((ch!='"') && (ch!='>'))

您正在过度运行header_name缓冲区,因为您未能在包含名称的末尾停止。

答案 4 :(得分:2)

错误在这里:

while((ch!='"') || (ch!='>')) /*until we get the end of header name*/

应该有&&(和)而不是||(或),因为这是一个无限循环。 (“重复而字符不是”或不是&gt;。“这两个条件中的至少一个始终为真,因此它会循环,直到出现分段错误。)

此外,您的源代码中还有许多其他缺陷。但是这个肯定会产生segmantetion错误。

附加说明:

  • 您的函数中应该只有一个参数:源文件名
  • FILE *c1_fp应该只是一个本地变量。
  • int c1_file_str_len应使用strlen()计算,并且必须添加1,否则您对第二个文件名的分配将错过'\0'
  • 您应该首选return;而不是exit(0);,并在退出前关闭文件并释放已分配的内存。

此外,您应该使函数递归,以便让它在#included文件中搜索#include指令。你应该支持“包含目录”设置 - 在哪里搜索.h文件的目录列表。