I'm trying to fill a gtk tree store from a linked list but i get the segmentation fault (core dumped) problem here is my code File to struct is a linked list filled a struct to a professor and a next the professor is defined by a name matiere password pseudo...etc
store = gtk_list_store_new (NUM_COLUMNNS,G_TYPE_INT,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_STRING,G_TYPE_INT);
File_to_struct *p=head;
/* add data to the list store */
while(p!=NULL)
{
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
COLUMNN_ID,p->professeur.ID,
COLUMNN_NOM,p->professeur.nom,
COLUMNN_MATIERE,p->professeur.matiere,
COLUMNN_PSEUD,p->professeur.pseudo,
COLUMNN_PASS,p->professeur.password,
COLUMNN_VALIDE,p->professeur.valide,
-1);
p=p->suivant;
}
FILE fichier=fopen("professeur.txt","r");
Prof professeur;
File_to_struct *tete=(File_to_struct)malloc(sizeof(File_to_struct));
tete=NULL;
rewind(fichier);
while((!feof(fichier)))
{
fscanf(fichier,"\n%s %s %s %s %d %d\n",professeur.nom,professeur.matiere,professeur.pseudo,professeur.password, &professeur.valide,&professeur.ID);
tete=inserer(tete,professeur); }
typedef struct prof{
int ID;
int valide;
char nom[40];
char matiere[40];
char password[40];
char pseudo[40]; }Prof;
typedef struct file_to_struct{
Prof professeur;
struct file_to_struct *suivant; }File_to_struct;
You have problems when filling the list, this is an example of how to do it correctly
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct Prof
{
int ID;
int valide;
char nom[40];
char matiere[40];
char password[40];
char pseudo[40];
} Prof;
typedef struct File_to_struct
{
Prof professeur;
struct File_to_struct *suivant;
} File_to_struct;
File_to_struct *
inserer(File_to_struct *Debut, Prof profs)
{
File_to_struct *nv;
File_to_struct *actuel;
nv = malloc(sizeof(File_to_struct));
if (nv == NULL)
return Debut;
nv->suivant = NULL;
nv->professeur = profs;
actuel = Debut;
if (Debut == NULL)
Debut = nv;
else
{
while (actuel->suivant != NULL)
actuel = actuel->suivant;
actuel->suivant = nv;
}
return Debut;
}
char **
splitString(const char *const text, const char *const delimiter, int *count)
{
char *copy;
char *pointer;
char *token;
char *saveptr;
char **list;
if ((text == NULL) || (count == NULL) || (delimiter == NULL))
return NULL;
copy = strdup(text);
*count = 0;
pointer = copy;
list = NULL;
while ((token = strtok_r(pointer, delimiter, &saveptr)) != NULL)
{
void *auxiliary;
auxiliary = realloc(list, (1 + *count) * sizeof(char *));
if (auxiliary == NULL)
{
while (*count >= 0)
{
free(list[*count]);
*count -= 1;
}
free(copy);
free(list);
return NULL;
}
list = auxiliary;
list[*count] = strdup(token);
*count += 1;
pointer = NULL;
}
free(copy);
return list;
}
Prof
extractProfesseur(const char *const line)
{
char **list;
int count;
Prof prof;
memset(&prof, 0, sizeof(prof));
list = splitString(line, " ", &count);
if (count < 6)
{
while (--count >= 0)
free(list[count]);
free(list);
return prof;
}
prof.ID = strtol(list[4], NULL, 10);
prof.valide = strtol(list[5], NULL, 10);
strncpy(prof.nom, list[0], 39);
strncpy(prof.matiere, list[1], 39);
strncpy(prof.pseudo, list[2], 39);
strncpy(prof.password, list[3], 39);
while (--count >= 0)
free(list[count]);
free(list);
return prof;
}
int
main()
{
FILE *fichier;
File_to_struct *tete;
File_to_struct *actuel;
char line[256];
fichier = fopen("professeur.txt","r");
if (fichier == NULL)
return -1; /* n'pouvez pas de ouvrir le fichier */
tete = NULL;
rewind(fichier);
while (fgets(line, sizeof(line), fichier) != NULL)
{
Prof professeur;
professeur = extractProfesseur(line);
tete = inserer(tete, professeur);
}
actuel = tete;
while (actuel != NULL)
{
Prof prof;
File_to_struct *previous;
prof = actuel->professeur;
previous = actuel;
actuel = actuel->suivant;
printf("%s %s %s %s %d %d\n", prof.nom, prof.matiere,
prof.pseudo, prof.password, prof.valide, prof.ID);
free(previous);
}
fclose(fichier);
return 0;
}
Related
I have a list of products of several categories in the file "Magazzino.txt" here below:
A451XX (codice prodotto)
CAT001 (codice categoria)
PASTA CONF. 1KG
100
99.0
A451XY (codice prodotto)
CAT002 (codice categoria)
MAGLIA LANA
25
6.70
A452XX (codice prodotto)
CAT001 (codice categoria)
SUGO
33
9.99
First I have to read the file and copy all products in a list with the following structure:
typedef struct {
char codP[C];
char codC[C];
char descr[D];
int num;
float costo;
} tipoBaseLista;
typedef struct nodoLista{
tipoBaseLista info;
struct nodoLista *next;
}prodotto;
typedef prodotto *listaP;
I need to copy this list of products in a list of categories such that each category has a sublist with all product that belong to the specific category. The structure of this list of list is:
typedef struct nodoCat{
char codC[C];
struct nodoCat *next;
listaP nodoP; //puntatore al sottonodo prodotto
}categoria;
typedef categoria *listaC;
This is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define C 8
#define D 64
typedef struct {
char codP[C];
char codC[C];
char descr[D];
int num;
float costo;
} tipoBaseLista;
typedef struct nodoLista{
tipoBaseLista info;
struct nodoLista *next;
}prodotto;
typedef prodotto *listaP;
typedef struct nodoCat{
char codC[C];
struct nodoCat *next;
listaP nodoP;
}categoria;
typedef categoria *listaC;
int carica_lista(char fName[], listaP *l);
void inserimentoProd(listaP *l, tipoBaseLista p);
listaC trovaCategoria(listaC lc, char categoria[]);
void inserimentoSottolista(listaC lc, tipoBaseLista p, listaP *l);
int main() {
char filename[] = "Magazzino.txt";
listaP lista = NULL;
listaC listaCat = NULL;
tipoBaseLista prodotto;
printf("\nNumero prodotti caricati: %d\n", carica_lista(filename, &lista));
if(lista == NULL){
printf("\nLa lista dei prodotti è vuota!\n");
}
while(lista != NULL){
prodotto = lista->info;
if(listaCat == NULL){
listaCat = malloc(sizeof(categoria));
strcpy(listaCat->codC, prodotto.codC);
listaCat->next = NULL;
inserimentoSottolista(listaCat, prodotto, &lista);
}
else{
listaCat = trovaCategoria(listaCat, prodotto.codC);
if(listaCat != NULL){
inserimentoSottolista(listaCat, prodotto, &lista);
}
else{
listaCat = listaCat->next;
inserimentoSottolista(listaCat, prodotto, &lista);
}
}
lista = lista->next;
}
return 0;
system("PAUSE");
}
//read from file
int carica_lista(char fName[], listaP *l) {
tipoBaseLista prodotto;
int n = 0;
char buf[D] = {0};
char scarto[30];
FILE *f;
f = fopen(fName, "r");
if (f == NULL) {
printf("Non e' possibile aprire il file\n");
exit(1);
}
while (!feof(f)) {
fgets(buf, sizeof(buf), f);
sscanf(buf, "%s%s", prodotto.codP, scarto);
fgets(buf, sizeof(buf), f);
sscanf(buf, "%s%s", prodotto.codC, scarto);
fgets(buf, sizeof(buf), f);
strcpy(prodotto.descr, buf);
fgets(buf, sizeof(buf), f);
sscanf(buf, "%d", &prodotto.num);
fgets(buf, sizeof(buf), f);
sscanf(buf, "%f", &prodotto.costo);
inserimentoProd(l, prodotto);
n++;
}
fclose(f);
return n;
system("PAUSE");
}
//to insert product in the list
void inserimentoProd(listaP *l, tipoBaseLista p){
listaP pCorrente = NULL;
listaP pNodo;
listaP pPrec;
pNodo = malloc(sizeof(prodotto));
pNodo->info = p;
pNodo->next = NULL;
if (*l == NULL){
*l = pNodo;
}
else if(strcmp(p.codP, (*l)->info.codP) < 0){
pNodo->next = *l;
*l = pNodo;
(*l)->next = pNodo;
}
else{
pCorrente = *l;
while (pCorrente->next != NULL && strcmp(p.codP, pCorrente->info.codP) > 0){
pPrec = pCorrente;
pCorrente = pCorrente->next;
}
if(strcmp(p.codP, pCorrente->info.codP) < 0){
pNodo->next = pCorrente;
pPrec->next = pNodo;
}
else if(pCorrente->next == NULL) {
pCorrente->next = pNodo;
}
}
}
//To find the category node under which we insert the sublist
listaC trovaCategoria(listaC lc, char categoria[]){
listaC pCorrente = lc;
while(pCorrente != NULL){
if(strcmp(pCorrente->codC, categoria) == 0){
printf("\nCategoria già presente.\n");
return pCorrente;
}
pCorrente = pCorrente->next;
}
return(NULL);
}
//to insert the product in the head of sublist
void inserimentoSottolista(listaC lc, tipoBaseLista p, listaP *l){
printf("\nInserimento nella sottolista\n");
listaP prodotto = malloc(sizeof(struct nodoLista));
prodotto->info = p;
prodotto->next = *l;
*l = prodotto;
lc->nodoP = prodotto;
printf("\nInserimento effettuato\n");
}
There must be some problem in the "inserimentoSottolista" that cause the crash of the program. What could it be?
The problem is here, inside inserimentoSottolista:
listaP prodotto = malloc(sizeof(prodotto));
You need sizeof(prodotto) to be the size of the struct that was declared earlier, i.e. sizeof(struct nodoLista). But you have used the same name for the name of the variable being initialized. In this case, the prodotto in sizeof(prodotto) isn't the struct, but is the variable. So sizeof(prodotto) ends up being the same as sizeof(listaP), which is just the size of a pointer. It's too small, so you aren't allocating enough memory.
You can fix it by changing the variable name so that it doesn't mask the type name, or by using sizeof(struct nodoLista).
I am trying to insert strings in the binary search tree.
So what I am to trying is,
parsing strings from a file(contains instruction set) and then inserting in the function
insertOpcodeFromFile().
So this function will execute
(*node) = Node_insert(&node,instruction).
the node will be the root of binary tree which is located in main function.
So in simple way to explain, I want to manipulate(insert) the root pointer in the main function by using double pointer in the other function contain insert function.
I have a simple understanding about the pointer, but in this situation, I need to use more than double pointer I think.
please explain me about the double pointer clearly using this example.
Here is my code(I commenting out insert_node)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef BINARYTREE_H_
#define BINARYTREE_H_
typedef struct node *NodePtr;
typedef struct node {
char *word;
int count;
NodePtr left;
NodePtr right;
} Node;
NodePtr Node_alloc();
NodePtr Node_insert(NodePtr node_ptr, char *word);
void clearArray(char a[]);
void insertOpcodeFromFile(FILE *opcodeFile, NodePtr *node);
void Node_display(NodePtr);
char *char_copy(char *word);
#endif
int main(int argc, const char * argv[]) {
FILE * opFile;
FILE * progFile;
struct node *root = NULL;
if ( argc != 4) { // # of flag check
fprintf(stderr, " # of arguments must be 4.\n" );
exit(1);
}
opFile = fopen ( argv[1], "r");
if(opFile == NULL)
{
fprintf(stderr,"There is no name of the opcode file\n");
exit(1);
}
progFile = fopen ( argv[2], "r");
if(progFile == NULL)
{
fprintf(stderr,"There is no name of the program file \n");
exit(1);
}
insertOpcodeFromFile(opFile, &root);
//Node_display(root);
}/* main is over */
void insertOpcodeFromFile(FILE *opcodeFile, NodePtr *node)
{
int fsize = 0;
int lengthOfInst = 0;
int c;
int i;
char buffer[100];
fsize = getFileSize(opcodeFile);
enum flag {ins,opc,form};
int flag = ins;
char instruction[6];
unsigned int opcode = 0;
unsigned char format;
while (c != EOF)
{
c = fgetc(opcodeFile);
buffer[i++] = c;
if (c == 32){
switch (flag) {
case ins:
flag = opc;
memcpy(instruction,buffer,i);
instruction[i] = '\0';
clearArray(buffer);
i = 0;
// printf("인스트럭션 : %s\n",instruction );
break;
case opc:
flag = form;
opcode = atoi(buffer);
clearArray(buffer);
i = 0;
// printf("옵코드 : %d\n",opcode );
break;
default:
break;
}/* end of switch */
}/* end of if(space) */
if((c == 10) || (c == EOF))
{
if (flag == form)
{
format = buffer[0];
clearArray(buffer);
i = 0;
// printf("포멧: %c\n", format);
}
flag = ins;
//node = Node_insert(node,instruction);
}
}
//Node_display(node);
}
int getFileSize(FILE *opcodeFile)
{ int fsize = 0;
fseek(opcodeFile,0, SEEK_SET);
fseek(opcodeFile,0, SEEK_END);
fsize = (int)ftell(opcodeFile);
fseek(opcodeFile,0, SEEK_SET);
return fsize;
}
int countUntilSpace(FILE *opcodeFile, int currentPosition)
{ char readword[1];
char *space = " ";
char *nextLine = "/n";
int i = 0;
//printf("현재: %d\n",currentPosition );
while(1)
{
fread(readword, sizeof(char),1,opcodeFile);
i++;
if(strcmp(readword,space) == 0 || strcmp(readword,nextLine) == 0)
{
//printf("break\n");
break;
}
}
fseek(opcodeFile,currentPosition ,SEEK_SET);
//printf("끝난 현재 :%d\n",ftell(opcodeFile) );
//printf("%I : %d\n",i );
return i - 1;
}
void clearArray(char a[])
{
memset(&a[0], 0, 100);
}
NodePtr Node_alloc()
{
return (NodePtr) malloc(sizeof(NodePtr));
}
NodePtr Node_insert(NodePtr node_ptr, char *word)
{
int cond;
if (node_ptr == NULL) {
node_ptr = Node_alloc();
node_ptr->word = char_copy(word);
node_ptr->count = 1;
node_ptr->left = node_ptr->right = NULL;
} else if ((cond = strcmp(word, node_ptr->word)) == 0) {
node_ptr->count++;
} else if (cond < 0) {
node_ptr->left = Node_insert(node_ptr->left, word);
} else {
node_ptr->right = Node_insert(node_ptr->right, word);
}
return node_ptr;
}
void Node_display(NodePtr node_ptr)
{
if (node_ptr != NULL) {
Node_display(node_ptr->left);
printf("%04d: %s\n", node_ptr->count, node_ptr->word);
Node_display(node_ptr->right);
}
}
char *char_copy(char *word)
{
char *char_ptr;
char_ptr = (char *) malloc(strlen(word) + 1);
if (char_ptr != NULL) {
char_ptr = strdup(word);
}
return char_ptr;
}
In this case, in main(),
Node *root;
Why do you need to use a "double" pointer ( Node ** ) in functions that alter root is because root value as to be set in these functions.
For instance, say you want to allocate a Node and set it into root.
If you do the following
void alloc_root(Node *root) {
root = malloc(sizeof (Node));
// root is a function parameter and has nothing to do
// with the 'main' root
}
...
// then in main
alloc_root( root );
// here main's root is not set
Using a pointer to pointer (that you call "double pointer")
void alloc_root(Node **root) {
*root = malloc(sizeof (Node)); // note the *
}
...
// then in main
allow_root( &root );
// here main's root is set
The confusion comes probably from the Node *root in main, root being a pointer to a Node. How would you set an integer int i; in a function f? You would use f(&i) to call the function f(int *p) { *p = 31415; } to set i to the value 31415.
Consider root to be a variable that contains an address to a Node, and to set its value in a function you have to pass &root. root being a Node *, that makes another *, like func(Node **p).
I am trying to write a C program that provides autocomplete suggestions looking at the contents of a directory. I have most of it done, however I get errors where directory names contain symbols that are not alphabets (such as . , / _). I get errors whenever I try to change things, including array size and looping values. Could you please take a look at my code and suggest what changes I need to make to include symbols in autocomplete suggestions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#define MAX 1000
struct node {
int data;
struct node *array[26];
};
struct node* new_node(struct node *h)
{
int i;
h = malloc(sizeof (struct node));
for (i = 0; i < 24; ++i)
h->array[i] = 0;
return h;
}
struct node* insert(struct node *h, char *c, int value)
{
int i;
if (strlen(c) == 0)
return h;
if (h == NULL)
h = new_node(h);
struct node *p = h;
for (i = 0; i < strlen(c); ++i) {
if (p->array[c[i] - 'a'] == NULL)
p->array[c[i] - 'a'] = malloc(sizeof (struct node));
p = p->array[c[i] - 'a'];
}
p->data = value;
return h;
}
int dfs(struct node *h, char *dat)
{
int i;
char k[1000] = {0};
char a[2] = {0};
if (h == NULL)
return 0;
if (h->data > 0)
printf("Match: %s\n", dat);
for(i = 0; i < 26; ++i) {
strcpy(k, dat);
a[0] = i + 'a';
a[1] = '\0';
strcat(k, a);
dfs(h->array[i], k);
}
}
void search(struct node *h, char *s, char *dat)
{
int i;
char l[1000] = {0};
char a[2];
strcpy(l, dat);
if (strlen(s) > 0) {
a[0] = s[0];
a[1] = '\0';
if(h->array[a[0]-'a'] != NULL) {
strcat(dat, a);
search(h->array[a[0]-'a'], s+1, dat);
} else
printf("No Match \n");
} else {
if (h->data != 0)
printf("Match: ");
for (i = 0; i < 26; ++i) {
strcpy(l, dat);
a[0] = i + 'a';
a[1] = '\0';
strcat(l, a);
dfs(h->array[i], l);
}
}
}
struct node* read_keys(struct node *h, char *file)
{
char s[MAX];
FILE *a = fopen(file, "r");
if (a == NULL)
printf("Error while opening file");
else
while (feof(a) == 0) {
fscanf(a, "%s", s);
h = insert(h, s, 1);
}
return h;
}
int main()
{
DIR *d;
struct dirent *dir;
char direct[MAX];
printf("Enter a folder name: ");
scanf("%s",direct);
d = opendir(direct);
FILE *f = fopen("file.txt", "w");
if (f == NULL)
{
printf("Error opening file!\n");
exit(1);
}
if (d)
{
while ((dir = readdir(d)) != NULL)
{
fprintf(f,"%s\n", dir->d_name);
}
}
fclose(f);
char c[1000];
FILE *fptr;
if ((fptr = fopen("file.txt", "r")) == NULL)
{
printf("Error! opening file");
exit(1);
}
FILE* file = fopen("file.txt", "r");
char line[1000];
while (fgets(line, sizeof(line), file)) {
printf("%s", line);
}
fclose(fptr);
printf("Enter beginning of filename \n");
struct node *h = 0;
h = read_keys(h, "file.txt");
char s[MAX];
scanf("%s", s);
char dat[1000] = "";
search(h, s, dat);
return 0;
}
I want to be able to use my getNextWord function to return a pointer to the next word in the file. I think I'm getting the seg fault while inserting but I just can't figure it out. Any help on this would be excellent. Also, I should probably find a better way of getting my hash_table_size than increasing a count for the total number of words in the file then rewinding. How can I make the size grow automatically?
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
int hash_table_size;
char* getNextWord(FILE* fd) {
char c;
char buffer[256];
int putChar = 0;
while((c = fgetc(fd)) != EOF) {
if(isalnum(c)) break;
}
if(c == EOF) return NULL;
buffer[putChar++] = c;
while((c = fgetc(fd)) != EOF) {
if(isspace(c) || putChar >= 256 -1) break;
if(isalnum(c))
buffer[putChar++] = c;
}
buffer[putChar] = '\0';
return strdup(buffer);
}
struct node {
struct node *next;
int count;
char* key;
};
struct list {
struct node *head;
int count;
};
struct list *hashTable = NULL;
/*
* djb2 hash function
*/
unsigned int hash(unsigned char *str) {
unsigned int hash = 5381;
int c;
while(c == *str++)
hash = ((hash << 5) + hash) + c;
return (hash % hash_table_size);
}
struct node* createNode(char *key) {
struct node *new_node;
new_node = (struct node *)malloc(sizeof(struct node));
strcpy(new_node->key, key);
new_node->next = NULL;
return new_node;
}
void hashInsert(char *str) {
int hash_dex = hash(str);
struct node *new_node = createNode(str);
if(!hashTable[hash_dex].head) {
hashTable[hash_dex].head = new_node;
hashTable[hash_dex].count = 1;
return;
}
new_node->next = (hashTable[hash_dex].head);
hashTable[hash_dex].head = new_node;
hashTable[hash_dex].count++;
return;
}
void display() {
struct node *current;
int i;
while(i < hash_table_size) {
if(hashTable[i].count == 0)
continue;
current = hashTable[i].head;
if(!current)
continue;
while(current != NULL) {
char tmp[256];
strcpy(tmp, current->key);
printf("%s", tmp);
current = current->next;
}
}
return;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: ./hashFile textfile\n");
}
else {
FILE *file = fopen(argv[1], "r");
if(file == 0) {
printf("Could not open file\n");
}
else {
char *new_word;
while((new_word = getNextWord(file)) != NULL) {
hash_table_size++;
}
rewind(file);
hashTable = (struct list *)calloc(hash_table_size, sizeof(struct list));
while((new_word = getNextWord(file)) != NULL) {
hashInsert(new_word);
}
display();
fclose(file);
}
}
return 0;
}
int c;
while(c == *str++)
hash = ((hash << 5) + hash) + c;
c is not initialized here. As is i in display function. Please enable all the compiler warnings and fix them.
Also:
char c;
char buffer[256];
int putChar = 0;
while((c = fgetc(fd)) != EOF) {
if(isalnum(c)) break;
}
c has to be of type int not char.
change
while(c == *str++)
to
while(c = *str++)
I was reading about how to implement a DPDA and found this code in the following Internet address: http://code.zhoubot.com/, This c file implements a simple pushdown automata. The automata will read in a description of their transition function and input, perform its computation on the input, and then print their output.
The input format is like:
e01:e0$:000111:a:ad:aeeb$:b0eb0:b10ce:c10ce:ce$de
The input is separated by a semicolon “:”, first section is “input alphabet”, second is “stack alphabet”, then “input” and the last whole bunch are transition functions.
/* This C file implements a Deterministic Pushdown Automata
* author: Kevin Zhou
* Computer Science and Electronics
* University of Bristol
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stack {
char content;
struct stack *next;
} Stack;
typedef struct transistion {
char current_state;
char input_symbol;
char pull;
char new_state;
char push;
} Transistion;
/* list of transistion functions */
typedef struct list {
Transistion *content;
struct list *next;
} List;
typedef struct pda {
char *input_alpha;
char *stack_alpha;
char *input;
char start;
char *accept;
List *transistion;
} PDA;
/* create a new empty stack */
Stack *create_stack( void ) {
Stack *s = calloc(1,sizeof(Stack));
if(s==NULL) {
printf("Out of Memory!");
exit(1);
}
return s;
}
/* test if the stack is empty */
int isempty( Stack *s ) {
return (s->next==NULL)? 1:0;
}
Stack *push_stack (Stack *s, char c) {
Stack *new = calloc(1,sizeof(Stack));
if(new ==NULL) {
printf("Out of Memory!");
exit(1);
}
new -> content = c;
new -> next = s;
return new;
}
Stack *pull_stack (Stack *s) {
Stack *head;
if(isempty(s)) {
return '\0';
}
head = s;
s = head -> next;
return s;
}
/*return the top elememt in the stack */
char top (Stack *s) {
return s->content;
}
/* replace a value 'ontop' which on top of the stack with a newvalue 'newvalue'
epsilon represents an empty element*/
Stack *replace(Stack *sta, char ontop, char newvalue, char epsilon) {
if(ontop == epsilon && newvalue == epsilon) return sta;
if(ontop == epsilon && newvalue != epsilon) {
sta = push_stack(sta,newvalue);
return sta;
}
if(ontop != epsilon && newvalue == epsilon) {
if(ontop != top(sta)) return NULL;
sta = pull_stack(sta);
return sta;
}
if(ontop != top(sta)) return NULL;
sta = pull_stack(sta);
sta = push_stack(sta,newvalue);
return sta;
}
/* turn the input string into transistion fields */
Transistion *get_transistion(char *s) {
Transistion *t = calloc(1,sizeof(Transistion));
t->current_state = s[0];
t->input_symbol = s[1];
t->pull = s[2];
t->new_state = s[3];
t->push = s[4];
return t;
}
/* turn the string into transitions and add into list */
List *insert_list( List *l, char *elem ) {
List *t = calloc(1,sizeof(List));
List *head = l;
while(l->next!=NULL)
l = l->next;
t->content = get_transistion(elem);
t->next = NULL;
l->next = t;
return head;
}
/* insert a transistion into a list */
List *insert_list_transistion( List *l, Transistion *tr) {
List *t = calloc(1,sizeof(List));
List *head = l;
while(l->next!=NULL)
l = l->next;
t->content = tr;
t->next = NULL;
l->next = t;
return head;
}
/*test if the char c is in the string s */
int contains ( char c, char *s ) {
int i=0;
while(1) {
if(c== s[i]) return 1;
if(s[i] == '\0') return 0;
i++;
}
}
/* test if the input is a valid input */
int is_valid_input( char *input_alpha, char *input ) {
int i=0;
char c;
while(1) {
c = input[i];
if(c == '\0') break;
if(!contains(c,input_alpha)) return 0;
i++;
}
return 1;
}
/* test if the input is a valid transistion */
int is_valid_transistion ( List *l, PDA *m) {
Transistion *t;
while(1) {
if(l==NULL) break;
t = l->content;
if(!contains(t->input_symbol,m->input_alpha)) return 0;
if(!contains(t->pull,m->stack_alpha)) return 0;
if(!contains(t->push,m->stack_alpha)) return 0;
l = l->next;
}
return 1;
}
/* create a pushdown automata */
PDA *createPDA (char *input) {
PDA *m = calloc(1,sizeof(PDA));
List *tr = calloc(1,sizeof(List));
char *buffer;
char *epsilon = calloc(1,sizeof(char));
/*read input alphabet of PDA*/
buffer = strtok(input,":");
if(buffer == NULL) {
printf("Error in reading input alphabet!\n");
exit(1);
}
m->input_alpha = buffer;
epsilon[0] = m->input_alpha[0];
/*read stack alphabet*/
buffer = strtok(NULL,":");
if(buffer == NULL) {
printf("Error in reading stack alphabet!\n");
exit(1);
}
m->stack_alpha = buffer;
/*read input sequence*/
buffer = strtok(NULL,":");
if(buffer == NULL) {
printf("Error in reading input sequence!\n");
exit(1);
}
if(!is_valid_input(m->input_alpha,buffer)) {
printf("Error! Input contains some invalid characters that don't match the input alphabet!\n");
exit(1);
}
m->input = buffer;
/*read start state*/
buffer = strtok(NULL,":");
if(buffer == NULL) {
printf("Invalid string!\n");
exit(1);
}
m->start = buffer[0];
/*read accept state*/
buffer = strtok(NULL,":");
if(buffer == NULL) {
printf("Invalid string!\n");
exit(1);
}
m->accept = buffer;
/*read transistion function*/
while(1) {
buffer = strtok(NULL,":");
if(buffer == NULL) break;
tr = insert_list(tr,buffer);
}
if(!is_valid_transistion(tr->next,m)) {
printf("Error! Invalid transistion functions!\n");
exit(1);
}
m->transistion = tr->next;
return m;
}
/*print a stack */
void print_stack2(Stack *s) {
if(s==NULL) {
return;
}
print_stack2(s->next);
printf("%c",s->content);
}
void print_stack(Stack *s) {
print_stack2(s);
printf("\n");
}
/* find a proper transition function for the current state */
Transistion *find_transistion(List *list,char input,char current,char e) {
Transistion *t;
while(1) {
if(list==NULL) return NULL;
t = list -> content;
if(t->current_state == current && t->input_symbol == input)
return t;
if(t->current_state == current && t->input_symbol == e)
return t;
list = list->next;
}
}
int isAccept(char current, char* accept) {
int i=0;
while(1) {
if(accept[i]=='\0') return 0;
if(accept[i]==current) return 1;
i++;
}
}
/*simulate the Pushdown automata */
void simulate(PDA *m) {
/* first symbol in input symbol used to represent the usual */
const char epsilon = m->input_alpha[0];
char current_state = m->start;
char input;
int i=0;
Stack *sta = create_stack();
Transistion *current_transistion;
Stack *backup;
while(1) {
/*get input*/
input = m->input[i];
if(input == '\0'&&isAccept(current_state,m->accept)) {
printf("Accept\n");
print_stack(sta);
break;
}
/*get transistion function*/
current_transistion = find_transistion(m->transistion,input,current_state,epsilon);
if(current_transistion==NULL) {
printf("Reject\n");
print_stack(sta);
break;
}
current_state = current_transistion->new_state;
backup = sta;
sta = replace(sta, current_transistion->pull, current_transistion->push,epsilon);
if(sta == NULL) {
printf("Reject\n");
print_stack(backup);
break;
}
if(current_transistion->input_symbol != epsilon&¤t_transistion->input_symbol != '\0')
i++;
}
}
void print(PDA *m) {
printf("input alphabet:%s\n",m->input_alpha);
printf("stack alphabet:%s\n",m->stack_alpha);
printf("input sequence:%s\n",m->input);
printf("start state:%c\n",m->start);
printf("accept state:%s\n",m->accept);
}
int main(void) {
char s[300];
PDA *p;
scanf("%s",s);
p = createPDA(s);
simulate(p);
return 0;
}
When trying to compile, the compiler tells me the following error:
Line 41: "error: invalid conversion from 'void *' to 'Stack *'
how I can fix this error, since I'm trying to understand
code?
You are likely using a C++ compiler instead of a C one. In C it's not required (it's actually discouraged) to cast void *. In C++ it's mandatory.
Incidentally, this C FAQ answers your problem. This one explains why casting void * can be problematic.