Here I am trying to implement a stack, where only opening braces from a string will be filtered out and stored in an array. The code I wrote stored the values in stackArr array. But whenever I attempt to print out the array, my code fails. It doesn't give any specific error message, it just fails to execute.
I think problem is in the following portion:
i = 0;
while(stackArr[i] != '\0')
{
printf("%c ",stackArr[i]);
i++;
}
Full code :
#include<stdio.h>
#include<stdlib.h>
int main()
{
char braces[10];
char stackArr[10];
int front = -1,rear = -1,size = 10;
gets(braces);
checkValidate(&braces,&stackArr,&front,&rear,size);
}
void checkValidate(char *braces,char *stackArr,int *front,int *rear,int size)
{
int i = 0;
while(braces[i] != '\0')
{
if((braces[i] == '(') || (braces[i] =='{') || (braces[i] =='['))
{
push(braces[i],&stackArr,&front,&rear,size);
}
i++;
}
//print(&front,&rear,size,*stackArr);
i = 0;
while(stackArr[i] != '\0')
{
printf("%c ",stackArr[i]);
i++;
}
}
void push (char val,char *stackArr,int *front,int *rear,int size)
{
if(isFull(*front,*rear,size))
{
printf("your string is larger that valid size\n");
}
else
{
if(isEmpty(*front,*rear))
{
*front = 0;
}
*rear = (*rear+1) % size;
stackArr[*rear] = val;
/*printf("%d ",*rear);
printf("%c",stackArr[*rear]);
printf("\n");*/
}
}
int isEmpty(int front,int rear)
{
if(front == -1 && rear == -1)
{
return 1;
}
else
{
return 0;
}
}
int isFull(int front,int rear,int size)
{
if(front == 0 && rear == size -1)
{
return 1;
}
else
{
return 0;
}
}
void print(int *front,int *rear,int size,char *arr)
{
int i;
for(i = *rear;i != *front; i = (i-1)% size)
{
printf("%c\n",arr[i]);
}
printf("%c\n",arr[i]);
}
Your code must produce a lot of warnings on compile, because the functions that you call lack forward declarations. Hence, compiler assumes that all functions that you call have parameters of type int, and that they also return an int. Since your functions take pointers instead, the calls of your functions result in undefined behavior, which is likely leading to a crash.
// Put these declarations in front of main
void checkValidate(char *braces,char *stackArr,int *front,int *rear,int size);
void push (char val,char *stackArr,int *front,int *rear,int size);
int isEmpty(int front,int rear);
int isFull(int front,int rear,int size);
void print(int *front,int *rear,int size,char *arr);
Adding forward declarations should fix this problem. In addition, you need to replace the now-deprecated gets call with a call to fgets, which is safe from buffer overruns.
You also pass pointers to arrays to functions that expect pointers to character. You need to remove & in front of braces and stackArr. Turn on compiler warnings to see all places where this needs to be done.
Finally, your code expects stackArr to be null-terminated, but you never set its elements to zeros. Add char stackArr[10] = {0} to initialize the array to zeros.
Related
output=[Error] 'is_empty' was not declared in this scope
must be:
Example
Input string : abbccbaabccbba message will be The string is valid
aaabbcbbcbaab message will be The string is invalid
aadbxcy*ycxbdaa message will be Wrong character!!!
what should i do?
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
typedef struct
{
char home[35];
int top;
} My_stack;
void push(My_stack * s, char c) // push (insert) operation
{ // assume there is enough space for pushing next element!
s -> top ++;
s -> home[s -> top] = c;
}
int pop(My_stack * s) // pop (remove) operation
{
if(is_empty (*s)) {
printf("ERROR: Nothing to pop - program terminates\n");
exit(1);
}
return (s ->home[s ->top --]);
}
int is_empty(My_stack * s) // checking whether stack is empty or not
{
return(s -> top < 0 ? 1 : 0);
}
int main(){
char ch[25];
int i,l;
My_stack stack;
printf("give the string");
scanf("%s",ch);
l=strlen(ch);
i=0;
while(ch[i]!='\0') {
if(ch[i]!='A'&&ch[i]!='B'&& ch[i]!='*') {
printf("the string is not accepted allowed caracters are A,B and * ");
exit(0);
}
i++;
}
i=0;
while(ch[i] != '*') {
push(&stack, ch[i]);
i++;
}
i++; // one step forward to pass '*
while(ch[i] != '\0') {
if(ch[i] != pop(&stack)) {
printf("the string is not valid");
exit(0);
}
i++;
}
printf("the string is valid");
return 0;
}
First of all, you need to pass the pointer to the function, not the actual value, so your functioncall must be changed to:
is_empty (s)
instead of
is_empty (*s)
Then, the reason is because you define your function is_empty after your first use. To prevent this error, you should declare your function first. This tells the compiler "hey, there exists this function with this signature, the definition is given later though" so then you can use it in your program before having implemented it explicitly.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
typedef struct
{
char home[35];
int top;
} My_stack;
int is_empty(My_stack * s); // <----- DECLARATION OF FUNCTION
int pop(My_stack * s) // pop (remove) operation
{
if(is_empty (s)) {
printf("ERROR: Nothing to pop - program terminates\n");
exit(1);
}
return (s ->home[s ->top --]);
}
int is_empty(My_stack * s) // checking whether stack is empty or not
{
return(s -> top < 0 ? 1 : 0);
}
Or, you put the entire definition before your first use so then there's no need for a declaration:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
typedef struct
{
char home[35];
int top;
} My_stack;
int is_empty(My_stack * s) // checking whether stack is empty or not
{
return(s -> top < 0 ? 1 : 0);
}
int pop(My_stack * s) // pop (remove) operation
{
if(is_empty (s)) {
printf("ERROR: Nothing to pop - program terminates\n");
exit(1);
}
return (s ->home[s ->top --]);
}
I'm trying to implement the following function but my code is not functional. Any ideas why?
int *colecao_pesquisa_nome(colecao *c, const char *nomep, int *tam);
Return an indices array referring to the position of all plants that present the full
scientific name or any of the local names equal to nomep. Returns by reference the
array’s size (tam). If it’s unsuccessful, the function should return NULL.
int *colecao_pesquisa_nome(colecao *c, const char *nomep, int *tam)
{ if(c==NULL || nomep==NULL)return NULL;
long i=0,a,z=0,y=0;
int *indice=NULL;
for (i = 0; i < c->tamanho; i++)
{
if (strstr(c->plantas[i]->nome_cientifico, nomep)!= NULL)
{
indice=(int*)realloc(indice,sizeof(int)*(z+1));
indice[z]=i;
z=z+1;
}
if(strstr(c->plantas[i]->nome_cientifico, nomep) == NULL){
for(a=0;a<c->plantas[i]->n_alcunhas;a++){;
if (strstr(c->plantas[i]->alcunhas[a], nomep) != NULL){
indice=(int*)realloc(indice,sizeof(int)*(z+1));
indice[z]=i;
z=z+1;
break;
}
}
}
}
*tam=z;
return indice;
}
So, I have an array of a structures called vitorias (in English, "victories"), an array of structures and an array of that structure and an array of strings.
Structure and arrays:
char **sistema_eq;
typedef struct
{
int id;
char nome[MAX_CHARS];
int vit;
} vitorias;
The problem is that when I use cppcheck it gives an error saying:
(error) Common realloc mistake: 'conj_vit' nulled but not freed upon failure
(error) Common realloc mistake: 'sistema_eq' nulled but not freed upon failure
(error) Common realloc mistake: 'conj_jogos' nulled but not freed upon failure
And, if I use Valgrind, it says that I did 10 allocs and 2 free, but I don't understand what's wrong, because I freed everything in the end I think.
Program:
#include<stdlib.h>
#include<stdio.h>
#include <string.h>
#define MAX_CHARS 1024 /* max characters of a word */
#define MAX_SIZE 5
static int size_until = 0; /*conts the size of sistema_eq and conj_vit*/
static int line = 1; /* counts the number of lines of the stdin */
int ident = 0; /*conts the id of jogos*/
static int size_until = 0; /*counts the size of sistema_eq*/
static int size_until2 = 0;/*counts the size of conj_jogos*/
void a(char nome_jg[],char team1[],char team2[],int score1,int score2);
void A(char nome[]);
char **sistema_eq;
jogo *conj_jogos;
vitorias *conj_vit;
int main()
{
char c;
char nome_jg[MAX_CHARS], team1[MAX_CHARS], team2[MAX_CHARS];
int score1;
int score2;
int i;
conj_jogos = (jogo*)calloc(MAX_SIZE,sizeof(jogo));
memset(conj_jogos,0, MAX_SIZE*sizeof(jogo));
conj_vit = (vitorias*)calloc(MAX_SIZE,sizeof(vitorias));
memset(conj_vit,0, MAX_SIZE*sizeof(vitorias));
sistema_eq = (char**)calloc(MAX_SIZE,sizeof(*sistema_eq));
memset(sistema_eq,0, MAX_SIZE*sizeof(*sistema_eq));
for(i=0;i<MAX_SIZE;i++)
{
sistema_eq[i] = (char*)calloc(1024,sizeof(char));
memset(sistema_eq[i],0, sizeof(char)*1024);
}
while ((c = getchar())!= 'x') {
switch (c)
{
case 'A':
{
scanf("%1023[^:\n]",nome_jg);
remove_esp(nome_jg);
A(nome_jg);
break;
}
case 'a':
{
scanf("%1023[^:\n]:%1023[^:\n]:%1023[^:\n]:%d:%d",nome_jg,team1,team2,&score1,&score2);
remove_esp(nome_jg);
a(nome_jg,team1,team2,score1,score2);
line++;
break;
}
}
}
free(conj_vit);
free(conj_jogos);
free(sistema_eq);
return 0;
}
/*This functions adds a victory and a equipa (team in english) into the corresponding arrays and updates the vitories of each team*/
//Example in El Classico Barcelona vs Real Madrid 1:0, which means Barcelona won
void A(char nome[])
{
if (nome_in_sis(nome) == 1)
{
printf("%d Equipa existente.\n",line);
line++;
}
else
{
if (size_until < MAX_SIZE)
{
strcpy(sistema_eq[size_until],nome);
strcpy(conj_vit[size_until].nome,nome);
conj_vit[size_until].id = size_until;
size_until++;
line++;
}
else
{
conj_vit = realloc(conj_vit,sizeof(vitorias)*(size_until+1));
sistema_eq = realloc(sistema_eq,sizeof(char*)*(size_until+1));
sistema_eq[size_until] = calloc(1024,sizeof(char*));
strcpy(sistema_eq[size_until],nome);
strcpy(conj_vit[size_until].nome,nome);
conj_vit[size_until].id = size_until;
size_until++;
line++;
}
}
}
/*This functions adds a jogo (game in english) and a equipa (team in english) into the array conj_jogos (the array of jogos)*/
void a(char nome_jg[],char team1[],char team2[],int score1,int score2)
{
int vit;
if (jogo_in(nome_jg) == 1)
{
printf("%d Jogo existente.\n",line);
line++;
}
else if ((nome_in_sis(team1) == 0) || (nome_in_sis(team2) == 0))
{
printf("%d Equipa inexistente.\n",line);
line++;
}
else
{
if (size_until2 < MAX_SIZE)
{
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
if (score1 > score2)
{
vit = procura_vit(team1);
conj_vit[vit].vit++;
}
else
{
vit = procura_vit(team2);
conj_vit[vit].vit++;
}
size_until2++;
}
else
{
size_until2++;
conj_jogos = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
conj_jogos[size_until2] = cria_jogo(nome_jg,team1,team2,score1,score2);
if (score1 > score2)
{
vit = procura_vit(team1);
conj_vit[vit].vit++;
}
else
{
vit = procura_vit(team2);
conj_vit[vit].vit++;
}
size_until2++;
}
}
}
Sorry if the code looks messy and thanks for the help.
As pointed out in the comments, you never free the data you allocated with calloc in the for loop. Add this loop (or something very similar) near the end of your main:
//...
for(i=0;i<MAX_SIZE;i++) free(sistema_eq[i]); // MUST be before the next line!
free(sistema_eq);
//...
Also, as you use calloc, you don't need any of the memset calls! From the linked documentation for void* calloc( size_t num, size_t size ):
Allocates memory for an array of num objects of size and initializes
all bytes in the allocated storage to zero.
For the 'errors' reported concerning realloc: in cases where a call to realloc fails, the code you use will prevent subsequent freeing of the original data (the address of which was in the pointer), as its address will be replaced with NULL on such a failure! To prevent this, use a temporary pointer, like this:
jogo* temp_jogo = realloc(conj_jogos,sizeof(jogo)*(size_until2+1));
if (temp_jogo != NULL) conj_jogos = temp_jogo;
else {
// In case of failure, we now still have the original conj_jogos
// pointer, which we can then pass to "free" at some point, presumably
// after we've signalled and/or handled the allocation error.
}
Finally (I think), you may like to read this: Do I cast the result of malloc? - which is equally valid for calls to calloc and realloc.
I am trying to implement an array based stack in C. My stack is supposed to have two parameters, top (the number of the top element in the array), and array (the array itself). My implementation follows.
typedef struct
{
char array[20];
int top;
}
stack;
stack mystack;
int Push(char,stack);
char Pop(stack);
char Top(stack);
int isFull(stack);
char input;
char save;
void main()
{
mystack.top = -1;
printf("Please input the characters you would like in your stack \n
while(input != '^')
{
Push( (scanf("%c",&input)) , mystack );
if (isFull(mystack) == 1)
printf("Your Stack is full, please input '^'\n");
}
char junk;
scanf("enter any character to continue %c",&junk);
while(mystack.top != -1)
{
printf("%c \n",Pop(mystack));
}
scanf("enter any character to terminate the program",&junk);
}
int Push(char charpush,stack stackpush)
{
if(stackpush.top >=20 )
return -1;
else
{
stackpush.array[stackpush.top + 1] = charpush;
stackpush.top = stackpush.top +1;
return 0;
}
}
char Pop(stack stackpop)
{
if (stackpop.top != -1)
{
save = stackpop.array[stackpop.top];
stackpop.top = stackpop.top-1;
return save;
}
}
char Top(stack stacktop)
{
if (stacktop.top != -1)
return stacktop.array[stacktop.top];
}
int isFull(stack stackisfull)
{
if (stackisfull.top = -1)
return 0;
else if (stackisfull.top >= 20)
return 1;
else return -1;
}
Currently my program accepts characters from the user, but the program automatically terminates when '^' is entered. It doesn't display the stack, and it doesn't do anything if characters come through the input and the stack is already full.
Please let me know if i need to be more specific or any further information is needed.
You've got a whole lot of problems to correct...
You have misunderstood scanf greatly
It doesn't return what it read
It doesn't accept a prompt
When reading from the terminal, it doesn't "see" anything until return is pressed
What does your method Pop() return when the stack is empty?
What does your method Top() return when the stack is empty?
Why did you write while(mystack.top != -1)? Would it make more sense to write while (!isEmpty(mystack)) and then write an isEmpty method?
You didn't initialize input - do yo know what is in it at the start?
Your indention "scheme" makes my head hurt. :)
In addition to the points #John Hascall has mentioned, C is a pass by value language. Meaning for every function call the arguments you provide are local in scope see this other stackoverflow post.
Having your global mystack variable (not the best practice either) will work but not how you are currently using it. By passing mystack to each function the changes are only visible on the argument used thereby defeating the purpose of having that global.
I've made the minor edits to indentation and logical errors but the main change was editing your functions to not take a "stack" argument and use your global:
#include <stdio.h>
typedef struct
{
char array[20];
int top;
} stack;
stack mystack; // your global
int Push(char); // remove "stack" arg for each stack-utility function
char Pop(void);
char Top(void);
int isFull(void);
char input;
char save;
// main as returning int and excepting argc/*argv[]
int main(int argc, char *argv[])
{
mystack.top = -1;
printf("Please input the characters you would like in your stack \n");
while(input != '^')
{
// by including scanf inside the function call return is passed
scanf("%c", &input);
Push( input );
if (isFull() == 1)
printf("Your Stack is full, please input '^'\n");
}
char junk;
// scanf will not print
printf("enter any character to continue\n");
scanf("%c",&junk);
while(mystack.top != -1)
{
printf("%c \n",Pop());
}
// same as last comment
printf("enter any character to terminate the program\n");
scanf("%c",&junk);
}
int Push(char charpush)
{
if(mystack.top >=20 )
return -1;
else
{
mystack.array[mystack.top + 1] = charpush;
mystack.top = mystack.top +1;
return 0;
}
}
char Pop(void)
{
if (mystack.top != -1)
{
save = mystack.array[mystack.top];
mystack.top = mystack.top-1;
return save;
}
// return has to match declaration type
return 0;
}
char Top(void)
{
if (mystack.top != -1)
return mystack.array[mystack.top];
// same as last comment
return 0;
}
int isFull(void)
{
// you were assigning not comparing
if (mystack.top == -1)
return 0;
else if (mystack.top >= 20)
return 1;
else return -1;
}
I am trying to implement a Boyer Moore Horsepoole algorithm. This code was written in Turbo C++, Windows. It worked. I have to port this in ubuntu.
typedef struct skip_table
{
char index;
int value;
}skip_table;
void create_table(char*,int);
int discrete_char(char*,int);
int bm(char*, char*);
int lookup(char);
int check_EOF(char*,int);
skip_table *t1;
int tab_len;
FILE *fptr;
int main()
{
time_t first, second;
double time_spent;
long int cnt=0;
char *key_string,*buf,c; // String to be matched and text
int i,key_len,text_len,def_shift_len,flag_match=0;
gets(key_string);
key_len=strlen(key_string);
fptr=fopen("test_file.txt","r");
first = clock();
fseek(fptr,SEEK_SET,0);
create_table(key_string,key_len);
while(flag_match!=1)
{
fseek(fptr,100*cnt,0);
fread(buf,100-key_len-1, 1, fptr);
flag_match = bm(buf, key_string);
cnt++;
printf("\n%d",cnt);
}
second =clock();
time_spent=(double)(second-first)/CLOCKS_PER_SEC;
if(flag_match==1)
printf("\n\nMatch Found in %lf seconds",time_spent);
else
printf("\n\nMatch NOT Found in %lf seconds",time_spent);
fclose(fptr);
return 0;
}
int discrete_char(char* key_string,char* temp,int key_len)
{
int i,j,count=1,flag=0;
for(i=1;i<key_len;i++)
{
for(j=0; j<count; j++)
{
flag=0;
if(temp[j] == key_string[i])
{
flag=1;
break;
}
}
if(flag!=1)
{
temp[count++]=key_string[i];
flag=0;
}
}
temp[count]='\0';
return count;
}
void create_table(char* key_string,int key_len)
{
int i,j,k,max_index;
char *temp;
temp[0] = key_string[0];
tab_len=discrete_char(key_string,temp,key_len);
t1=(skip_table*)malloc((tab_len-1)*sizeof(skip_table));
for(i=0;i<tab_len;i++)
{
for(j=0;j<key_len;j++)
{
if(temp[i]==key_string[j])
max_index=j;
}
t1[i].index=temp[i];
t1[i].value=key_len-max_index-1;
printf("\n\n %c %d",t1[i].index,t1[i].value);
}
}
int bm(char* text, char* key_string)
{
int i_t, i_k, j,k, text_len, key_len, shift, count=0, flag_match=0;
int loop_count;
text_len = strlen(text);
key_len = strlen(key_string);
i_t=key_len;
i_k=key_len;
loop_count=0;
while(i_t<=text_len)
{
if(count != key_len)
{
if(text[i_t-1]==key_string[i_k-1])
{
count++;
i_t--; i_k--;
loop_count++;
}
else
{
if(loop_count>key_len)
{
i_t=i_t+lookup(text[i_t-1])+1;
i_k=key_len;
loop_count=0;
continue;
}
shift = lookup(text[i_t-1]);
if(shift<=0)
shift=key_len;
i_t = i_t+shift;
i_k = key_len;
count=0;
}
}
else
{
flag_match = 1;
break;
}
}
return flag_match;
}
"int lookup(char index)" returns the respective value field of the index if present in "temp" else returns -1.
There's my whole code.
Not that I see exactly what went wrong but here are some defensive programming tips:
int main()
{
// initialize all variables before use
time_t first = 0, second = 0;
double time_spent = 0.0;
long int cnt=0;
char *key_string = NULL;
char *buf = NULL;
char c = '\0';
char temp[50] = {0};
int i = 0,key_len=0,text_len=0,def_shift_len=0,flag_match=0;
// use fgets instead of gets, fgets allows you specify max length
fgets(temp,sizeof(temp),stdin);
key_len=strlen(temp);
key_string = (char*) malloc(key_len+1);
// use strncpy or strcpy_s to specify max size
strncpy(key_string, temp, sizeof(key_string));
fptr = fopen("test_file.txt","r");
first = clock();
// here arguments have wrong order, fseek takes origin as last arg:
fseek(fptr,0,SEEK_SET);
// could be something in create_table, but you have not supplied it
create_table(key_string,key_len);
When you have so many variables in a function you may consider moving out parts of the function to other functions
Try using --track-origins=yes on your valgrind options as well, as the output suggests, this can help track down where uninitialised varables have come from.
As others have suggested, the issue valgrind is reporting is inside create_table, so please post the code for that as well.