简体   繁体   English

C Linux中的分段错误(核心转储)

[英]Segmentation fault (core dumped) in c linux

My code returns a Segmentation fault and I do not know why. 我的代码返回了细分错误,但我不知道为什么。

It prints part of the output and gives a Segmentation fault. 它输出部分输出并给出分段错误。 I cannot find the error. 我找不到错误。

It should number words & sentences & paragraphs & top words with highest frequencies in order. 它应该按顺序为频率最高的单词,句子,段落和最重要的单词编号。

Here is my code: 这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "preprocessing_header.h"
#include "calculations_header.h"


int main(int argc, char* argv[])
{
  if (argc != 3)
  {
    printf("Error: number of arguments must be 3\n");
    exit(-1);
  }

  char* file_name;
  file_name = argv[1];
  int N = atoi(argv[2]);

  char final_string[number_of_char_aprox];
  char *string;
  string = Preprocessing(file_name);
  strcpy(final_string, string);
  printf("%s\n", final_string);

  calculations(final_string, N);

  return 0;
}


/* The main function for sorting the file in the appropriate form */
char* Preprocessing(char file_name[])
{
  char final_string[number_of_char_aprox];
  char *string;

  FILE *in = fopen(file_name,"r");
  if (in == NULL) {
    printf("Not found");
    exit(-1);
  }
  Head lines_list = (Head)malloc(sizeof(struct line)); // list of the lines from the file
  lines_list->next = NULL;

  readFile(lines_list, in); // read the file and put each line in a node in the list
  fclose(in);

  remove_spaces(lines_list); // make only a single space after each word in the lines
  to_lower(lines_list); // convert all charachter in each line to small letter
  punctuation_marks(lines_list); // make a one single space after punctuation marks
  lines_list = reverse_list(lines_list); // reverse the list

  string = concat_string(lines_list);// put all line in one string
  strcpy(final_string, string);
  free_list(lines_list);

  string = Atter_punctuation_marks(final_string); // make letters atter punctuation 
  strcpy(final_string, string);

  string = add_point(final_string);
  strcpy(final_string, string);

  //string = remove_line_feed(final_string);// remove line feed in the same paragraph
  //strcpy(final_string, string);

  string = final(final_string);// the final form of the string

  return string;
}


/* Make the needed calculations */
void calculations(char final_string[],int N)
{
  int i;
  int number_of_words;
  int number_of_sentences;
  int number_of_paragraphs;

  Head_word lw[26];// array of linked list of the words
  for(i = 0; i < 26; i++)
  {
    lw[i] = (Head_word)malloc(sizeof(struct word));
    lw[i]->next = NULL;
  }

  number_of_words = count_words(final_string, lw);
  number_of_sentences = count_sentences(final_string);
  number_of_paragraphs = count_paragraphs(final_string);

  printf("\n******************************************************\n\n");
  printf("\n******************************************************\n\n");
  printf("number_of_words = %d\n",number_of_words);
  printf("\nnumber_of_sentences = %d\n",number_of_sentences);
  printf("\nnumber_of_paragraphs = %d\n",number_of_paragraphs);
  printf("\n******************************************************\n\n");
  printf("Top %d words with highest frequencies in order : \n\n",N);

  Head_word most_repeated[N];
  most_repeated_words(lw,most_repeated, N);
  free_lists_words(lw);
  sort(most_repeated,N); //sort the most frequently used words
  print_most_repeated_words(most_repeated, N);
}

here is preprocessing_header.h 这是preprocessing_header.h

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

/*read the file and put each line in a node in a linked list*/
void readFile(Head l, FILE *in)
{
position p;
while(!feof(in))
{
    p = (position)malloc(sizeof(struct line));
    fgets(p->string,10000,in);
    p->next = l->next;
    l->next = p;
 }
 }

 /* make only a single space after each word in the lines*/
void remove_spaces(Head l)
{
int i = 0;
int j = 0;
int k;
position p = l->next;
char temp[1000];

while(p != NULL)
{
    i = 0;
    j = 0;
    for(k = 0;k<1000;k++)
    {
        temp[k] = '\0';
    }
    while(p->string[i] != '\0')
    {
        if(p->string[0] == ' ')
        {
            while(p->string[i] == ' ')
                i++;
        }
        while(p->string[i] != ' ' && p->string[i] != '\0')
        {
            temp[j] = p->string[i];
            i++;
            j++;
        }
        while(p->string[i] == ' ')
        {
            i++;
        }
        temp[j++] = ' ';
    }
    temp[j+1] = '\0';
    strcpy(p->string,temp);
    p = p->next;
  }

}

void to_lower(Head l)
{
position p = l->next;
int i = 0;
while(p != NULL)
{
    i = 1;
    while(p->string[i] != '\0')
    {
        if(p->string[i]>= 65 && p->string[i]<=90)
        {
            p->string[i]+= 32;
        }
        i++;
    }
    p = p->next;
   }
}
/*make a one single space after punctuation marks and no space before it*/
void punctuation_marks(Head l)
{
position p = l->next;
int i,j,k;
char temp[1000];
while(p != NULL)
{
    i = 0;
    j = 0;
    for(k = 0;k<1000;k++)
    {
        temp[k] = '\0';
    }
    while(p->string[i] != '\0')
    {
        if(p->string[i] == '.' || p->string[i] == ',' || p->string[i] == ';'   ||p->string[i] == '?' )
        {
            if(p->string[i-1] == ' ')
            {
               temp[--j] = p->string[i];
            }
            if(p->string[i+1] != ' ')
            {
                temp[j++] = p->string[i++];
                temp[j++] = ' ';
            }
        }
        temp[j++] = p->string[i++];
    }
    temp[j+1] = '\0';
    strcpy(p->string,temp);
    p = p->next;
  }
  }
 /*reverse linked list*/
 Head reverse_list(Head l)
 {
Head l2 = (Head)malloc(sizeof(struct line));
l2->next = NULL;
position p = l->next;
while(p != NULL)
{
    l->next = p->next;
    p->next = l2->next;
    l2->next = p;
    p = l->next;
 }
free(l);
return l2;
}
  /* put all line in one string*/
 char* concat_string(Head l)
 {
char *temp = malloc(number_of_char_aprox*sizeof(char));
int k;
for(k = 0;k<number_of_char_aprox;k++)
{
    temp[k] = '\0';
}
position p = l->next;
while(p != NULL)
{
    strcat(temp,p->string);
    p = p->next;
}
return temp;
}
/*remove line feed in the same paragraph*/
char* remove_line_feed(char final_string[])
{
int i;
char *temp = malloc(number_of_char_aprox*sizeof(char));

for(i = 0;i<number_of_char_aprox;i++)
{
    temp[i] = '\0';
}

int j=0;
  //printf("%s",final_string);
for(i = 0;i<strlen(final_string);i++)
{


   if(final_string[i] == 13)
   {
       if(final_string[i-2]== '.')
       {
           temp[j++] = final_string[i++];
       }
       else
       {
           i = i+2;
       }
   }
   temp[j++] = final_string[i];
   }
   return temp;
 }
/*make letters atter punctuation marks capital letters*/
char* Atter_punctuation_marks(char string[])
{
 char *temp = malloc(number_of_char_aprox*sizeof(char));
int k;
int i=0,j=0;
for(k = 0;k<number_of_char_aprox;k++)
{
    temp[k] = '\0';
}
while(string[i] != '\0')
{
    if(string[i] == '.'  || string[i] == ';' ||string[i] == '?' || string[i] == '\n' )
    {
        if(string[i+2] >= 97 && string[i+2]<=122)
        {
            temp[j++] = string[i++];
            temp[j++] = string[i++];
            temp[j++] = string[i++]-32;
        }
    }
    if(string[i] == 'i' && string[i-1] == ' ' && string[i+1] == ' ')
    {
        string[i]-= 32;
    }
    temp[j++] = string[i++];
}
    temp[j+1] = '\0';
    return temp;
 }
char* to_lower_case(char string[])
 {
int i = 0;
while(string[i] != '\0')
    {
        if(string[i]>= 65 && string[i]<=90)
        {
            string[i]+= 32;
        }
        i++;
     }
    return string;
  }
/*make only one empty line between paragraphs and return the stirng with the final   form*/
 char* final(char s[])
 {
int i;
int j = 0;
char *temp = malloc(number_of_char_aprox*sizeof(char));

for(i = 0;i<number_of_char_aprox;i++)
{
    temp[i] = '\0';
}
j = 0;
for(i = 0;i<strlen(s);i++)
{
     if(s[i]== ' ' && s[i-1] == '\n')
    {
            i++;
    }
    if(s[i] == '\n')
    {
        while(s[i+3] == '\n')
        {
            i+=3;
        }
        temp[j++] = '\n';
    }

    temp[j++] = s[i];
}

 return temp;
 }
void free_list(Head l)
 {

position temp;
while(l->next != NULL)
{
    temp = l->next;
    l->next = temp->next;
    free(temp);
 }
 free(l);
 }
char* add_point(char s[])
 {
int i,j=0;
char *temp = (char*)malloc(10000*sizeof(char));

for(i=0;i<strlen(s);i++)
{
    if(s[i]==13 && !strchr(".,?;",s[i-1]) && !strchr(".,?;",s[i-2]) )
    {

            temp[j++] = '.';
            i++;
    }
    temp[j++] = s[i];
 }
 return temp;
   }

and here is my calculations_header.h 这是我的calculations_header.h

 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "calculations_header.h"
 /*count the number of words in the string and put the word in an array of linked list
 which index is the first letter in each word eg (a)re in the linked list of index 0.
 The word will be put in the list if it is a new word only if it is repeated the      counter
     of the node containing the word will increase*/
   int count_words(char string[],Head_word lw[])
  {
int i,j,k=0, length=0, count=0;
char word[50];
position_word p;
for(j=0;j<50;j++)
{
    word[j] = '\0';
}
length= strlen(string);
for (i=0; i<length; i++)
{
    if((string[i] == ' ' && string[i+1] != ' ') || string[i] == 10 || string[i] == 13)
    {
        if(!is_exist(word,lw[word[0]-97]))
        {
    //printf("%s\n",word);
            p = (position_word)malloc(sizeof(struct word));
            strcpy(p->string,word);
            p->counter = 1;
            p->next = lw[word[0]-97]->next;
            lw[word[0]-97]->next = p;
        }
    //printf("%d",word[1]);
        //printf("%s\n",word);


    if((word[1]>=97 && word[1]<=123) || (word[1]>=65 && word[1]<=91))
         count++;
        k = 0;
for(j=0;j<50;j++)
        {
            word[j] = '\0';
        }
    }
    if((string[i]>=97 && string[i]<=123) || (string[i]>=65 && string[i]<=91))
    {
        if(string[i] >= 65 && string[i] <= 90)
        {
            word[k] = string[i]+32;
        }
        else
        {
          word[k] = string[i];
        }
        k++;
    }
   }
   return count;
  }

  /*test if the word is exist in the list*/
 int is_exist(char word[], Head_word l)
 {
int flag = 0;
Head_word p;
p = l->next;
while(p!=NULL)
{
    if(strcmp(word,p->string) == 0)
    {
        p->counter++;
        flag = 1;
        break;
    }
    p = p->next;
   }
   return flag;
  }

 /*decide which N word are the most frequently used*/
 void most_repeated_words(Head_word lw[],Head_word most_repeated[],int n)
 {
int i,j;
int least;
position_word p;
for(i = 0 ;i<n;i++)
{
    most_repeated[i] = (Head_word)malloc(sizeof(struct word));
    most_repeated[i]->next = NULL;
    most_repeated[i]->counter = 0;
}
for(i = 0;i<26;i++)
{
    p = lw[i]->next;
    while(p!= NULL)
    {
        for(j = 0 ; j<n;j++)
        {
            if(p->counter > most_repeated[j]->counter)
            {
                least = get_least(most_repeated,n);
                strcpy(most_repeated[least]->string,p->string);
                most_repeated[least]->counter = p->counter;
                break;
            }
        }
        p = p->next;
    }

   }

  }

 /*get the least repeated word in the array*/
int get_least(Head_word l[],int n)
{
int i;
int least = 10000;
int index;
for(i = 0;i<n;i++)
{
    if(l[i]->counter < least)
    {
        least = l[i]->counter;
        index = i;
    }
  }
  return index;
}
  /*count the number of sentences*/
   int count_sentences(char s[])
  {
int i;
int count = 0;
for(i=0;i<strlen(s);i++)
{
    if(strchr(".?;,",s[i]))
    {
        count++;
    }
}
return count;
  }
  /*count the number of paragraphs*/
  int count_paragraphs(char s[])
   {
   int i;
  int count = 0;
   for(i=0;i<strlen(s);i++)
  {
    if(s[i] == '\n' && s[i+1]>=65 && s[i+1]<=90 )
    {
        count++;
    }
  }
  return count+1;
  }
  /*print the most repeated N words and how many time it has been used*/
 void print_most_repeated_words(Head_word most_repeated[],int N)
  {
int i;
for(i=0;i<N;i++)
{
    printf("%s\t%d\n",most_repeated[i]->string,most_repeated[i]->counter);
  }
 }

 /*sort the N most frequently used word in ascending order */
 void sort(Head_word most_repeated[],int N)
  {

int i,j;
Head_word temp = (Head_word)malloc(sizeof(struct word));
 for (i = 0 ; i < ( N - 1 ); i++)
 {
for (j = 0 ; j < N - i - 1; j++)
  {
  if (most_repeated[j]->counter < most_repeated[j+1]->counter)
  {

    temp->counter = most_repeated[j]->counter;
    strcpy(temp->string,most_repeated[j]->string);

    most_repeated[j]->counter = most_repeated[j+1]->counter;
    strcpy(most_repeated[j]->string,most_repeated[j+1]->string);

    most_repeated[j+1]->counter = temp->counter;
    strcpy(most_repeated[j+1]->string,temp->string);
     }
   }
 }
}
void free_lists_words(Head_word l[])
{
int i;
position_word temp;
for(i = 0;i<26;i++)
{
    while(l[i]->next != NULL)
    {
        temp = l[i]->next;
        l[i]->next = temp->next;
        free(temp);
    }
    free(l[i]);
   }

}

and here is my calculations_header.h: 这是我的calculations_header.h:

 #ifndef CALCULATIONS_HEADER_H_INCLUDED
#define CALCULATIONS_HEADER_H_INCLUDED

/*This structure to save each word to make calculations*/
typedef struct word *ptr_word;
struct word
{
char string[50];
int counter;
ptr_word next;
};
typedef ptr_word Head_word;
typedef ptr_word position_word;

/*calculation functions prototypes*/
char* Preprocessing(char []);
void calculations(char [],int);
int count_words(char [],Head_word[]);
int is_exist(char [], Head_word);
void print(Head_word[]);
void most_repeated_words(Head_word [],Head_word[],int);
int get_least(Head_word[],int);
int count_paragraphs(char []);
int count_sentences(char []);
void print_most_repeated_words(Head_word[],int);
void sort(Head_word [],int);
void free_lists_words(Head_word []);

 #endif // CALCULATIONS_HEADER_H_INCLUDED

and here is my preprocessing_header.h: 这是我的preprocessing_header.h:

  #ifndef PREPROCESSING_HEADER_H_INCLUDED
  #define PREPROCESSING_HEADER_H_INCLUDED
 #define number_of_char_aprox 10000

/*This structure for saving each line read from the file*/
 typedef struct line *ptr;
 struct line
 {
 char string[10000];
 ptr next;
 };
typedef ptr Head;
typedef ptr position;

 /*preprocessing functions prototypes*/
void readFile(Head,FILE *);
void remove_spaces(Head);
void to_lower(Head);
void punctuation_marks(Head );
Head reverse_list(Head);
char* concat_string(Head);
void free_list(Head);
char* Atter_punctuation_marks(char []);
char* remove_line_feed(char []);
char* final(char []);

 #endif // PREPROCESSING_HEADER_H_INCLUDED

it give me just warning on line 60 in main( string = add_point(final_string); ) 它只是在main(string = add_point(final_string);)的第60行上给我警告

i think the function calculations it make the error. 我认为函数计算会导致错误。

char final_string[number_of_char_aprox];

What's number_of_char_aprox ? 什么是number_of_char_aprox You don't even declare it as a variable. 您甚至都没有将其声明为变量。 A segmentation fault happens when you are trying to access not assigned memory. 当您尝试访问未分配的内存时发生分段错误。 As there is no value for that variable (actually there is no variable at all), it probably defaults to 0 (or NULL, or imploding universe, who knows), and when you use it to reserve memory for final_string you got your segmentation fault. 由于该变量没有值(实际上根本没有变量),它可能默认为0(或NULL或内爆的宇宙,谁知道),当您使用它为final_string保留内存时,您会遇到分段错误。

By the way, DDD is a great graphical debugger. 顺便说一下,DDD是一个出色的图形调试器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM