Desigine a NFA but not working - c

I designed this NFA - where I input a string, and the output is Accepted if this NFA accept it else Not accepted.
My code is here -
#include <stdio.h>
#include <stdlib.h>
int accepted = 1;
struct node
{
char first, second;
struct node *left, *right;
};
int main()
{
struct node *stage, *start, *temp;
char A[50000], data;
printf("String: ");
gets(A);
int i;
for(i=0; i<strlen(A); i++)
{
if(i==0)
{
stage=(struct node*)malloc(sizeof(struct node));
if(A[i] == '0')
{
stage->first = 'B';
stage->second = 'A';
}
else if(A[i] == '1')
{
stage->first = 'A';
stage->second = '\0';
}
stage->left = '\0';
start = stage;
temp = stage;
stage->right = '\0';
}
else
{
stage=(struct node*)malloc(sizeof(struct node));
temp->right = stage;
stage->left = temp;
if(A[i] == '0')
{
if(temp->first = 'A')
{
stage->first = 'B';
stage->second = 'A';
}
else if(temp->first = 'B')
{
stage->first = '\0';
stage->second = '\0';
}
else if(temp->first = 'C')
{
stage->first = '\0';
stage->second = '\0';
}
else if(temp->first = '\0')
{
while(1)
{
stage = stage->left;
temp = stage->left;
stage->right = '\0';
i--;
if(i == 0)
{
accepted = 0;
break;
}
if(stage->second != '\0')
{
stage->first = stage->second;
stage->second = '\0';
break;
}
}
}
}
else if(A[i] == '1')
{
if(temp->first = 'A')
{
stage->first = 'A';
stage->second = '\0';
}
else if(temp->first = 'B')
{
stage->first = 'C';
stage->second = '\0';
}
else if(temp->first = 'C')
{
stage->first = 'C';
stage->second = '\0';
}
else if(temp->first = '\0')
{
while(1)
{
stage = stage->left;
temp = stage->left;
stage->right = '\0';
i--;
if(i == 0)
{
accepted = 0;
break;
}
if(stage->second != '\0')
{
stage->first = stage->second;
stage->second = '\0';
break;
}
}
}
}
temp = stage;
stage->right = '\0';
}
}
temp = start;
printf("\n");
while(1)
{
printf("%c => ", temp->first);
temp = temp->right;
if(temp->right == '\0')
{
data = temp->first;
break;
}
}
if(accepted && data == 'C') printf("\n\nAccepted.\n");
else printf("\n\nNot accepted.\n");
return 0;
}
Please help me to find, what's wrong there.

Related

reversed string not being returned in a c function in program of infix to prefix

Below is the code for infix to prefix conversion. My code works fine until the use of reverse function where it does not print any string after copying. I have tried using a for loop to copy the reversed string but the outcome remains the same and the program terminates without giving proper output. Print statements in the reverse function work before copying but not after that. Could anyone let me know where the problem is?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stack{
int size;
int top;
char *arr;
};
void display(struct stack *ptr)
{
if(ptr->top == -1)
{
printf("Stack is Empty");
}
else
{
for(int i = ptr->top ; i>=0 ; i--)
{
printf("Element: %d\n",ptr->arr[i]);
}
}
}
int isEmpty(struct stack *ptr)
{
if(ptr->top == -1)
{
return 1;
}
else
{
return 0;
}
}
int isFull(struct stack *ptr)
{
if(ptr->top == ptr->size - 1)
{
return 1;
}
else
{
return 0;
}
}
void push(struct stack *ptr,int data)
{
if(isFull(ptr))
{
printf("Stack Overflow");
}
else
{
ptr->top = ptr->top + 1;
ptr->arr[ptr->top] = data;
}
}
char pop(struct stack *ptr)
{
if(isEmpty(ptr))
{
printf("Stack Underflow");
return 0;
}
else
{
char ch = ptr->arr[ptr->top];
ptr->top = ptr->top - 1;
return ch;
}
}
char stackTop(struct stack *ptr)
{
return ptr->arr[ptr->top];
}
int isOperator(char a)
{
if(a == '+'|| a == '-'|| a == '*'|| a == '/')
{
return 1;
}
else
{
return 0;
}
}
int precedence(char a)
{
if(a == '*' || a == '/')
{
return 3;
}
else if(a == '+' || a == '-')
{
return 2;
}
else
{
return -1;
}
}
char * reverse(char exp[])
{
int l = strlen(exp);
int j = 0;
char temp[l];
for(int i=l-1;i>=0;i--,j++)
{
temp[j] = exp[i];
}
temp[j] = '\0';
printf("prefix is %s",temp);
strcpy(exp,temp);
// for(int i=0;i<=l;i++)
// {
// exp[i] = temp[i];
// }
printf("prefix is %s",exp);
return exp;
}
char * infix_prefix(char *infix)
{
struct stack *sp = (struct stack *) malloc(sizeof(struct stack));
sp->size = 100;
sp->top = -1;
sp->arr = (char *) malloc(sp->size * sizeof(char));
char *prefix = (char *) malloc((strlen(infix+1)) * sizeof(char));
infix = reverse(infix);
int i=0;
int j=0;
while(infix[i] != '\0')
{
if(infix[i] == ')')
{
push(sp,infix[i]);
i++;
}
else if(infix[i] == '(')
{
while(!isEmpty(sp) && stackTop(sp) != ')')
{
prefix[j] = pop(sp);
j++;
}
if(!isEmpty(sp))
{
pop(sp);
i++;
}
else
{
printf("Incorrect Expression");
exit(0);
}
}
else if(!isOperator(infix[i]))
{
prefix[j] = infix[i];
i++;
j++;
}
else if(isOperator(infix[i]))
{
while(!isEmpty(sp) && precedence(infix[i])<=precedence(stackTop(sp)))
{
prefix[j] = pop(sp);
j++;
}
push(sp,infix[i]);
i++;
}
else
{
printf("Incorrect expression");
exit(0);
}
}
while(!isEmpty(sp) && stackTop(sp) != '(')
{
prefix[j] = pop(sp);
j++;
}
if(stackTop(sp) == ')')
{
printf("Incorrect expression");
exit(0);
}
prefix = reverse(prefix);
prefix[j] = '\0';
return prefix;
}
int main(void)
{
char *infix = "(x-y/z-k*d)";
printf("prefix is %s",infix_prefix(infix));
return 0;
}
The reverse indeed has a problem: the temp array is defined with a length of l: that's not long enough to store the null terminator at temp[j] after the loop, causing undefined behavior.
There are more problems:
char *prefix = (char *) malloc((strlen(infix+1)) * sizeof(char)); does not allocate enough space for a copy of infix. You should write char *prefix = malloc(strlen(infix) + 1);
infix = reverse(infix); will crash because the argument to infix_prefix is a string literal which must not be modified. You should declare the argument as const char *infix and make a modifiable copy with strdup() if reversing is really needed, which I doubt very much.
Here is a modified version of reverse that performs the reverse operation in place:
char *reverse(char exp[]) {
int i = 0;
int j = strlen(exp);
while (j-- > i) {
char c = exp[j];
exp[j] = exp[i];
exp[i++] = c;
}
return exp;
}

Infix to Postfix using C stuck execution after halfway. Can any one tell me why?

I've been trying implementing Infix to Postfix using Stack(using LL) in C Language. When I first executed the code with input like(e.g: a+b/c*d-e) it's showing the correct notation from infix to postfix. So I think Everything is working fine but after modifying the code to accept input consisting brackets when I'm trying to input expressions having brackets its gets stuck mid way of execution. I don't know why?
Please help me.
Thanks in Advance
Below is the Code
#include <stdlib.h>
struct stackPara
{
char data;
struct stackPara *next;
};
int isEmpty(struct stackPara *top)
{
if (top == NULL)
return 1;
else
return 0;
}
int isFull(struct stackPara *top)
{
struct stackPara *p = (struct stackPara *)malloc(sizeof(struct stackPara));
if (p == NULL)
return 1;
else
return 0;
}
struct stackPara *pushStack(struct stackPara *top, char n)
{
struct stackPara *ptr = (struct stackPara *)malloc(sizeof(struct stackPara));
ptr->data = n;
if (!isFull(top))
{
ptr->next = top;
top = ptr;
//printf("Insert %c\n", top->data);
}
else
{
printf("Stack is FULL");
}
return top;
}
char popStack(struct stackPara **top)
{
char x = '\0';
struct stackPara *p = (*top);
if (!isEmpty((*top)))
{
x = (*top)->data;
(*top) = (*top)->next;
free(p);
}
else
{
printf("Stack is Empty");
}
return x;
}
void displayLL(struct stackPara *ptr)
{
// struct stackPara *ptr=top;
printf("Elements of Stack are:\n");
while (ptr != NULL)
{
printf("Data:%d\n", ptr->data);
ptr = ptr->next;
}
}
int isOperand(char ch)
{
return (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '1' && ch <= '9');
}
int isOperator(char ch)
{
if (ch == '+' || ch == '-')
return 1;
if (ch == '*' || ch == '/')
return 2;
if (ch == '^')
return 3;
return 0;
}
void infixToPostfix(char *exp)
{
struct stackPara *top = NULL;
for (int i = 0; exp[i] != '\0'; i++)
{
if (isOperator(exp[i]))
{
if (isEmpty(top))
{
top = pushStack(top, exp[i]);
// printf("%c",exp[i]);
// displayLL(top);
}
else
{
if (isOperator(exp[i]) > isOperator(top->data))
{
top = pushStack(top, exp[i]);
}
else
{
while (!isEmpty(top))
{
if (isOperator(exp[i]) <= isOperator(top->data))
{
printf("%c", popStack(&top));
}
}
top = pushStack(top, exp[i]);
}
}
}
if (isOperand(exp[i]))
{
printf("%c", exp[i]);
}
if (exp[i] == '(')
top = pushStack(top, exp[i]);
else if (exp[i] == ')')
{
while (top->data != '(')
{
printf("%c", popStack(&top));
}
if (top->data == '(')
{
popStack(&top);
}
else
{
printf("INVALID EXPRESSION");
break;
}
}
}
while (!isEmpty(top))
{
printf("%c", popStack(&top));
}
}
int main()
{
char *exp = "a+b*(c^d-e)^(f+g*h)-i\0";
infixToPostfix(exp);
return 0;
}```
> Output of Above Code:
>
> **abcd^**

C programming, only the first if statement works

I was wondering if anyone could help me understand why only my first if statements is working. Basically, I am working on a l33t speak convertor (lol) and only my first if statement works, here is my code:
#include<stdio.h>
#include<string.h>
void translate (char blurp[]);
int main(void) {
char message[1024];
printf("enter a message: \n");
fgets(message, 1024, stdin);
translate(message);
return 0;
}
void translate (char blurp[]) {
int i;
int length;
length = strlen(blurp);
printf("\nHere it is translated: \n");
for ( i = 0; i != length; i++) {
if (blurp[i] == 'a') {
blurp[i] = '4';
printf("%c", blurp[i]);
}
else if (blurp[i] == 'b') {
blurp[i] = '8';
printf("%c", blurp[i]);
}
else if (blurp[i] == 'e') {
blurp[i] = '3';
printf("%c", blurp[i]);
}
else if (blurp[i] == 'i') {
blurp[i] = '|';
printf("%c", blurp[i]);
}
else if (blurp[i] == 'o') {
blurp[i] = '0';
printf("%c", blurp[i]);
}
else if (blurp[i] == 's') {
blurp[i] = '5';
printf("%c", blurp[i]);
}
else {
printf("%c", blurp[i]);
}
}
}

Printing string pointers in c

So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.

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