Code give me segmentation fault - c

I don't know why my code gives me a segmentation fault.
Before it worked fine, so i must have done something to it,
but I don't know what.
This function gets some Markdown-Elements from a specific line in a file
and returns a dynamic array ( int * elements) with the elements
int * parser_getElements(char * string)
{
int * elements;
char * token, * temptoken;
int charcount = 0, elemcount = 1, i = 0;
assert(string != NULL);
elements = malloc(sizeof(int));
*elements = 0;
token = strtok(string," ");
while(token != NULL)
{
temptoken = token;
while (*temptoken)
{
charcount++;
++temptoken;
}
if(token[0] == '*' && token[charcount - 1] == '*')
{
if(token[1] == '*' && token[charcount - 2] == '*')
{
elements[elemcount-1] = EMPH;
}
else
{
if(token[1] != '*' && token[charcount - 2] != '*')
{
elements[elemcount-1] = ITAL;
}
}
elemcount++;
elements = realloc(elements,sizeof(int) * elemcount);
}
else if(token[0] == '_' && token[charcount - 1] == '_')
{
if(token[1] == '_' && token[charcount - 2] == '_')
{
elements[elemcount-1] = EMPH;
}
else
{
if(token[1] != '_' && token[charcount - 2] != '_')
{
elements[elemcount-1] = ITAL;
}
}
elemcount++;
elements = realloc(elements,sizeof(int) * elemcount);
}
else
{
elements[elemcount-1] = TEXT;
elemcount++;
elements = realloc(elements,sizeof(int) * elemcount);
}
token = strtok(NULL, " ");
charcount = 0;
}
return elements;
}
The problem occurs in the function below.
void parser_printMDElements(List markdown, FILE * out)
{
MD_Element element;
int count = 0, no_text = 0;
if(markdown != NULL)
{
element = markdown->value->elements[0];
while(element <= EMPH)
{
if(element > TEXT)
{
no_text = 1;
}
count++;
element = markdown->value->elements[count];
}
count = 0;
element = markdown->value->elements[0];
while(element <= EMPH)
{
if(no_text)
{
printf("%s\n",MD_Element_Descr[element]);
}
count++;
element = markdown->value->elements[count];
}
parser_printMDElements(markdown->next,out);
}
}
This line(first appearance)
element = markdown->value->elements[0];
gives me a segmentation fault and I don't know why.
The program stops after this line.
This is the main program
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "errors.h"
#include "parser.h"
int main(int argc, char * argv[])
{
Errorcode error = ERR_NULL;
char * gap;
int gapcount = 1;
List md = parser_newList();
/** Save name of document in firstnode */
md->value = malloc(sizeof(struct NodeValue));
md->value->string = argv[1];
md->type = DOCUMENT;
md->next = malloc(sizeof(struct Node));
error = parser_parseFile(argv[1],&(md->next));
if(error == ERR_NULL)
{
gap = malloc(sizeof(char));
*gap = '\0';
parser_printMDElements(md, gap, gapcount, stdout);
printf("\n");
}
return 0;
}
This code is extracted from parser.h
enum MD_Element
{
DOCUMENT,
LINE,
SECTION,
LISTELEMENT,
H1,
H2,
H3,
H4,
H5,
H6,
TEXT,
IMG,
LINK,
QUOTE,
CODE,
ITAL,
EMPH
};
typedef enum MD_Element MD_Element;
typedef struct NodeValue * NodeValue;
struct NodeValue
{
char * string;
int * elements;
};
typedef struct Node * Node;
struct Node
{
MD_Element type;
NodeValue value;
Node next;
};
typedef Node List;
Can sb. tell me what I've done wrong?
Thanks!

There are still many pieces of your code missing here.
I'm guessing that your problem is possibly in md->value->string = argv[1];.
(athough your question does not show how you are using md->value->string).
If you attempt to change the contents of the memory pointed by md->value->string, then you will have a memory access violation, since this variable is pointing to a read-only memory segment.
If that is indeed the case, then you can solve it by replacing md->value->string = argv[1]; with:
md->value->string = malloc(strlen(argv[1])+1);
strcpy(md->value->string,argv[1]);

Related

Cant insert Node to binary tree

I am trying to insert Node to Binary tree. This is my function for creating Node (rest is done).
void BVSCreate_function(TNodef *rootPtr, function_save token) {
TNodef *newPtr = malloc(sizeof(struct tnodef));
if (newPtr == NULL) {
fprintf(stderr, "99");
return;
}
TNodef init;
string initStr;
initStr.str = NULL;
initStr.length = 0;
initStr.alloc = 0;
newPtr = &init;
newPtr->content = &initStr;
newPtr->leftPtr = NULL;
newPtr->rightPtr = NULL;
newPtr->return_type = token.ret_value;
newPtr->parameters = token.param_count;
strCpyStr(newPtr->content, token.content);
rootPtr = newPtr;
}
void BVSInsert_function(TNodef *rootPtr, function_save token) {
if (rootPtr == NULL) {
BVSCreate_function(rootPtr, token);
} else {
if ((strCmpStr(token.content, rootPtr->content)) < 0) {
BVSCreate_function(rootPtr->leftPtr, token);
} else
if ((strCmpStr(token.content, rootPtr->content)) > 0) {
BVSCreate_function(rootPtr->rightPtr, token);
}
}
}
When TNodef and function_save are structs:
typedef struct {
string *content;
int param_count;
int ret_value;
} function_save;
typedef struct tnodef {
string *content;
struct tnodef *leftPtr;
struct tnodef *rightPtr;
int parameters;
int return_type;
} TNodef;
Where string is defined as this struct:
typedef struct {
char *str; // content of string
int length; // length of string
int alloc; // amount of memory allocated
} string;
strCpystr function :
int strCpyStr(string *s1, string *s2) {
int len2 = s2->length;
if (len2 > s1->alloc) {
if (((s1->str) = (char *)realloc(s1->str, len2 + 1)) == NULL) {
return 1;
}
s1->alloc = len2 + 1;
}
strcpy(s1->str, s2->str);
s1->length = len2 + 1;
return 0;
}
I am trying to create a node in binary tree and put there information from struct function_save.
But when I try to print this tree after insert it shows me that tree is still empty.
Your code in BVSCreate_function has undefined behavior because:
newPtr = &init; discards the allocated node and instead uses a local structure that will become invalid as soon as the function returns.
newPtr->content = &initStr; is incorrect for the same reason: you should allocate memory for the string too or possibly modify the TNodeDef to make content a string object instead of a pointer.
Function BVSInsert_function does not return the updated root pointer, hence the caller's root node is never updated. You could change the API, passing the address of the pointer to be updated.
There is also a confusion in BVSInsert_function: it should call itself recursively when walking down the tree instead of calling BVSCreate_function.
Here is a modified version:
/* Allocate the node and return 1 if successful, -1 on failure */
int BVSCreate_function(TNodef **rootPtr, function_save token) {
TNodef *newPtr = malloc(sizeof(*newPtr));
string *newStr = malloc(sizeof(*content));
if (newPtr == NULL || newStr == NULL) {
fprintf(stderr, "99");
free(newPtr);
free(newStr);
return -1;
}
newStr->str = NULL;
newStr->length = 0;
newStr->alloc = 0;
newPtr->content = newStr;
newPtr->leftPtr = NULL;
newPtr->rightPtr = NULL;
newPtr->return_type = token.ret_value;
newPtr->parameters = token.param_count;
strCpyStr(newPtr->content, token.content);
*rootPtr = newPtr;
return 1;
}
int BVSInsert_function(TNodef **rootPtr, function_save token) {
if (*rootPtr == NULL) {
return BVSCreate_function(rootPtr, token);
} else {
if (strCmpStr(token.content, rootPtr->content) < 0) {
return BVSInsert_function(&rootPtr->leftPtr, token);
} else
if ((strCmpStr(token.content, rootPtr->content)) > 0) {
return BVSInsert_function(&rootPtr->rightPtr, token);
} else {
/* function is already present: return 0 */
return 0;
}
}
}
Note also that function strCpyStr may write beyond the end of the allocated area is len2 == s1->alloc, assuming s1->len is the length of the string, excluding the null terminator.
Here is a modified version:
int strCpyStr(string *s1, const string *s2) {
int len2 = s2->length;
if (len2 >= s1->alloc) {
char *newstr = (char *)realloc(s1->str, len2 + 1);
if (newstr == NULL) {
return 1;
}
s1->str = newstr;
s1->alloc = len2 + 1;
}
strcpy(s1->str, s2->str);
s1->length = len2;
return 0;
}

Error while trying to make struct function

varibels
I have a function that gets an array and suppose to return a struct
The struct looks like this:
typedef struct
char name[16];
int year;
int month;
int day;
c }
and a function.
The function basically gets an array and divides the array to the struct. When I get to the end of the function, I'm getting a runtime error:
Run-Time Check Failure #2 - Stack around the variable 'temp_date' was corrupted.
Here is the function:
city cityspliter(char *info)
city temp;
int t,i, length;
char temp_date[2];
length = strlen(info);
for (i = 1; i < length; i++)
{
if (info[i] != '~')
temp.name[i - 1] = info[i];
else
{
temp.name[i - 1] = NULL;
break;
}
}
t = 0;
while (info[i+1]!='/')
{
temp_date[t] = info[i + 1];
i++;
t++;
}
temp.day = get_number(temp_date);
t = 0;
while (info[i + 1] != '/')
{
temp_date[t] = info[i + 1];
i++;
t++;
}
temp.month = get_number(temp_date);
while (info[i + 2] != '>')
{
temp_date[t] = info[i + 2];
i++;
t++;
}
temp.month = get_number(temp_date);
t = 0;
while (info[i] != '>')
{
temp_date[t] = info[i];
i++;
t++;
}
temp.year = get_number(temp_date);
return temp;
}
Any ideas what is wrong?

Insert function for Ternary Search Tree - C

I am new to C and am trying to code up a data structure, primarily, a ternary search tree. I am working under the assumption (for now) that valid char inputs are being passed in. I am having some issues with my insert function. Note that I am also inserting the original string in the last TSTnode where the last character of str will also be held.
Here is what I have so far
struct TSTnode {
char* word; // NULL if no word ends here
char self;
struct TSTnode *left, *sub, *right;
};
int insert_tst(struct TSTnode** tree, const char* str) {
return _insert(tree, str, 0);
}
int _insert(struct TSTnode** tree, const char* str, int position) {
if((*tree) == NULL) {
*tree = new_tst_node(*(str+position));
position = position + 1;
if(*(str+position) == '\0') {
(*tree)->word = strcpy((*tree)->word,str);
return 1;
}
}
else if ((*tree)->self > *(str+position)) {
position = position + 1;
_insert( &((*tree)->left), str, position);
}
else if ((*tree)->self < *(str+position)) {
position = position + 1;
_insert( &((*tree)->right), str, position);
}
else {
position = position + 1;
_insert( &((*tree)->sub), str, position);
}
return 0;
}
struct TSTnode* new_tst_node(char self) {
struct TSTnode* newNode = (struct TSTnode*) malloc(sizeof(struct
TSTnode));
if (newNode == NULL) {
return NULL;
}
newNode->word = NULL;
newNode->self = self;
newNode->left = NULL;
newNode->right = NULL;
newNode->sub = NULL;
return newNode;
}
Here is how I am testing:
struct TSTnode* tree = NULL;
char* words[1] = {"hello"};
for (int i = 0; i < 1; i++) {
if (insert_tst(&tree, words[i]) == 0) {
//print some error
}
else { //success }
EDIT - My issue is that none of my conditional branches are being taken and the insert function simply goes straight to return 0.
Note: You confusingly use tree for both TSTnode* and TSTnode**. I'm going to use tree_ptr for the latter, and pretend that you did the same.
Your claim is false. The body of if((*tree_ptr) == NULL) is executed. You do have a number of problems, though.
You don't handle the case where *tree_ptr == NULL && *(str+position+1) != '\0'.
You don't correctly handle the case where *tree_ptr != NULL && *(str+position+1) == '\0'.
You always return 0 when *tree_ptr != NULL || str[1] != '\0'.
You never allocate word, but you deference it. The thing is, you shouldn't be storing the string again anyway!
You don't handle the case where str[0] == '\0' (empty string).
Fixed:
int insert_tst(struct TSTnode** tree_ptr, const char* str) {
if (!*str)
return 0; /* Zero-length strings are not supported. */
return insert_tst_helper(tree_ptr, str, 0);
}
int insert_tst_helper(struct TSTnode** tree_ptr, const char* str, int position) {
if (*tree_ptr == NULL) {
*tree_ptr = new_tst_node(*(str+position));
if (*tree_ptr == NULL)
return 0; /* Memory allocation error. */
}
if (*(str+position+1) == '\0') { /* If the next char is a NUL */
(*tree_ptr)->is_word = 1;
return 1;
}
else if ((*tree_ptr)->self > *(str+position)) {
position = position + 1;
return insert_tst_helper( &((*tree_ptr)->left), str, position);
}
else if ((*tree_ptr)->self < *(str+position)) {
position = position + 1;
return insert_tst_helper( &((*tree_ptr)->right), str, position);
}
else {
position = position + 1;
return insert_tst_helper( &((*tree_ptr)->sub), str, position);
}
}
Untested.
Let's clean this up, though.
*(str+position)simplifies tostr[position]
ch == '\0'simplifies toch == 0then to!ch
position = position + 1; return insert_tst_helper(..., str, position);simplifies to++position; return insert_tst_helper(..., str, position);then toreturn insert_tst_helper(..., str, position+1);then toreturn insert_tst_helper(..., str+1, 0);then toreturn insert_tst(..., str+1);
Why is recursion being used at all???
Fixed:
int insert_tst(struct TSTnode** tree_ptr, const char* str) {
if (!*str)
return 0; /* Zero-length strings are not supported. */
while (1) {
if (*tree_ptr == NULL) {
*tree_ptr = new_tst_node(*str);
if (*tree_ptr == NULL)
return 0; /* Memory allocation error. */
}
if (!*(str+1)) { /* If the next char is a NUL */
(*tree_ptr)->is_word = 1;
return 1;
}
int cmp = *str - (*tree_ptr)->self;
if (cmp < 0) { tree_ptr = &( (*tree_ptr)->left ); }
else if (cmp > 0) { tree_ptr = &( (*tree_ptr)->right ); }
else { tree_ptr = &( (*tree_ptr)->sub ); }
++str;
}
}
Untested.

free() memory using a 'for' loop in a singly linked list

This is my complete program:
#include <stdio.h>
#include <stdlib.h>
#define kArraySize 50
#define kFirstElement 0
struct Name {
char name[kArraySize + 1];
struct Name *nextName;
} *gFirstNameNode, *gLastNameNode;
char GetName(struct Name *currentName);
void AddToList(struct Name *currentName);
void PrintList(struct Name *gFirst);
void FreeTheMemory(struct Name *gFirst);
int main(void) {
struct Name *currentName;
char character;
int counter;
gFirstNameNode = NULL;
gLastNameNode = NULL;
do {
currentName = malloc(sizeof(struct Name));
if (currentName == NULL) {
printf("Out of Memory!\n");
exit(0);
} else {
for (counter = 0; counter <= kArraySize; counter++)
currentName->name[counter] = '\0';
}
character = GetName(currentName);
if ((currentName->name[kFirstElement]) != '\0') {
AddToList(currentName);
}
} while (character != '\r');
PrintList(gFirstNameNode);
printf("Freeing list memory");
FreeTheMemory(gFirstNameNode);
printf("\nFreeing Current Memory!\n");
free(currentName);
printf("Program Ended");
return 0;
}
char GetName(struct Name *currentName) {
char c;
int counter = 0;
printf("Enter a name (hit 'return' to exit):");
for (counter = 0; (counter <= kArraySize) && ((c = getchar()) != '\n'); counter++) {
currentName->name[counter] = c;
}
if (counter == 0) {
return '\r';
} else {
currentName->name[counter + 1] = '\0';
return '\0';
}
}
void AddToList(struct Name *currentName) {
if (gFirstNameNode == NULL) {
gFirstNameNode = currentName;
} else {
gLastNameNode->nextName = currentName;
}
gLastNameNode = currentName;
currentName->nextName = NULL;
}
void PrintList(struct Name *gFirst) {
struct Name *currentPointer;
if (gFirstNameNode == NULL) {
printf("No names in list\n");
printf("----------------\n");
} else {
for (currentPointer = gFirst; currentPointer != NULL; currentPointer = currentPointer->nextName) {
printf("Name: %s\n", currentPointer->name);
}
}
}
void FreeTheMemory(struct Name *gFirst) {
struct Name *currentPointer;
for (currentPointer = gFirst; currentPointer != NULL; currentPointer = currentPointer->nextName) {
free(currentPointer);
printf(".");
}
}
This is where I'm uncertain as to whether what I'm doing is correct. I'm teaching myself C all by myself so please bear with me. What I want to do is delete the node of the linked list from the first node till the last node. For that I created the following function. :
void FreeTheMemory(struct Name *gFirst) {
struct Name *currentPointer;
for (currentPointer = gFirst; currentPointer != NULL; currentPointer = currentPointer->nextName) {
free(currentPointer);
printf(".");
}
}
I'm not sure if by freeing the currentPointer whether I'm actually freeing the linked list. In other words I'm wondering if my logic is correct. I've got no one to ask so I would greatly appreciate some help.
You have a problem doing this:
free(currentPointer);
followed by this:
currentPointer = currentPointer->nextName
You can't deference currentPointer to get the next name after you've freed it.
Instead you should do something like:
currentPointer = gFirst;
while ( currentPointer ) {
struct Name * next = currentPointer->nextName;
free(currentPointer);
currentPointer = next;
}

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
#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
#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:
#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:
#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); )
i think the function calculations it make the error.
char final_string[number_of_char_aprox];
What's 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.
By the way, DDD is a great graphical debugger.

Resources