What do I do with the error in implementing the stack? - c

#include <stdio.h>
#define stack 100
void push(int x);
int st[stack];
int top = -1;
int IsEmpty()
{
if (top < 0)
return false;
else
return true;
}
int Isfull()
{
if (top >= stack - 1)
return true;
else
return false;
}
void push(int x)
{
if (Isfull() == true)
printf("stack is full");
else
st[++top]=x;
}
int pop() {
if (IsEmpty() == true)
printf("stack is empty.");
else
return stack[top--];/// There is an error in this part. (expression must have pointer-to-object type)
}
int main()
{
push(3);
}
int pop() {
if (IsEmpty() == true)
printf("stack is empty.");
else
return stack[top--];There is an error in this part. (expression must have pointer-to-object type)
expression must have pointer-to-object type
Stack is being implemented as an array And then there's this error.
What should I do?
Is this a Syntex error? Tell me the wrong part.
and If there is anything else that needs to be corrected, please let me know.
C language is difficult. Have you all experienced this kind of error?

return stack[top--]; same as return 100[top--];.
I suspect you wanted return st[top--];
Use a different name for the stack size too to avoid such name collisions.
// #define stack 100
#define STACK_SIZE 100

I see 3 problems:
A simple typo:
return stack[top--]; ==> return st[top--];
stack is the array size but your array is named st
Missing return value
This code has no return value when the stack is empty.
int pop() {
if (IsEmpty() == true)
printf("stack is empty.");
// No return value here
else
Even if the stack is empty you must return a value. So you need to handle that in another way. One option is to return a dummy value (e.g. zero), another is to exit the program or change the pop-function signature so that it can tell whether it was succesful. For instance:
// Option 1: Return dummy value
int pop() {
if (IsEmpty()) return 0;
return stack[top--];
}
// Option 2: Exit program
int pop() {
if (IsEmpty()) exit(1);
return stack[top--];
}
// Option 3: Let the function tell whether is was a success
int pop(int* data) {
if (IsEmpty()) return 0;
*data = stack[top--];
return 1;
}
The last pop-function returns 1 on success - zero otherwise.
Wrong logic
This function:
int IsEmpty()
{
if (top < 0)
return false;
else
return true;
}
is wrong. Change it to:
int IsEmpty()
{
if (top < 0)
return true;
else
return false;
}
or more simple
int IsEmpty()
{
return (top < 0);
}

Related

Checking balanced parentheses in a string with stacks in c

I am trying to write a program where i implement stacks with arrays and use them to check if a given string has balanced parentheses.
For ex. if inputted '(()){}[()]' ,program would output 'Balanced', otherwise if inputted '({})[' the program would output 'Not balanced'.
This part is the array implementation of the stack.
#include <stdio.h>
#include <stdlib.h>
#define MAX 50
int stack[MAX];
int top=-1;
void push(char val){
if(top==MAX-1){
printf("stack is already full,error\n");
}else{
top++;
stack[top]=val;
}
}
char pop(){
if(top==-1){
printf("not enough elements,error\n");
exit(1);
}else{
top--;
return stack[top];
}
}
This part is the implementation of a common method to solve the problem.
int isMatching(char c1, char c2){
if(c1=='{' && c2=='}')
return 1;
else if(c1 =='(' && c2==')')
return 1;
else if(c1=='[' && c2==']')
return 1;
return 0;
}
int isBalanced(char str[]){
int i=0;
while(str[i]!='\0'){
if(str[i]=='{' || str[i]=='[' || str[i]=='('){
push(str[i]);
}
if(str[i]==')' || str[i] == ']' || str[i]=='}'){
if(stack==NULL){
return 0;
}
if(!isMatching(pop(), str[i])){
return 0;
}
}
i++;
}
if(stack==NULL){
return 1; // balanced parenthesis
}else{
return 0; // not balanced parenthesis
}
}
And this is the main function where the user inputs a string and it's tested if it's 'Balanced' or not.
int main(){
char str[MAX];
int flag;
printf("Enter the string with the brackets and etc.\n");
fgets(str, sizeof(str),stdin);
flag=isBalanced(str);
if(flag==1){
printf("Balanced\n");
}
else{
printf("Not balanced\n");
}
return 0;
}
When i input a very simple example, i get a wrong answer, for instance
Enter the string with the brackets and etc.
()
Not balanced
This is supposed to output 'Balanced' instead.I don't understand how this could have occured.
in pop(), you are decrementing before returning the top element. Change:
top--;
return stack[top];
to
return stack[top--];
Also, in isBalanced(), stack is NEVER null, so delete:
if(stack==NULL){
return 0;
}
and change the balanced check to look for the empty stack from:
if(stack==NULL){
return 1; // balanced parenthesis
}else{
return 0; // not balanced parenthesis
}
To:
if(top==-1){
return 1; // balanced parenthesis
}else{
return 0; // not balanced parenthesis
}
After making these changes, your code appeared to work on my box. This isn't quite how I'd have coded it, but this is the minimal set of changes to make it work.
if (stack==NULL) is the problem here, stack will never be NULL.
You need to check if there are still elements in your stack, by verifying that top > 0
You implemented the push/pop combo wrong. If you push one character top becomes 0. If you popping it immediately it finally executes top--; return stack[top], which evaluates to stack[-1].
Try this push/pop:
int top=-1; //idx to be popped next; <0 -> invalid
void push(char val)
{
if(top==MAX-2)
printf("stack is already full,error\n");
else
stack[++top]=val;
}
char pop()
{
if(top<0) return '\0'; //no abort, just return invalid char
return stack[top--];
}
The answer to your question has already been satisfactorily answered, but as a suggestion for a different approach, consider the following.
Since there are only a very small number of common enclosures used within C source code you can easily track pairs of them using an increment-decrement counter. The following uses a struct, typedefed to balanced_s which is encapsulated into a function to simplify the evaluation. Following is a sample implementation:
typedef struct {
int paren;
int curly;
int square;
bool bBal
}balanced_s;
balanced_s * balanced_enclosures(const char *source);
int main(void)
{
char in[5000] = {0};//you could improve this by reading file size
//first then creating array sized accordingly
FILE *fp = fopen("C:\\play\\source.c", "r");//using copy of this source to test
if(fp)
{
size_t bytes = fread(in, 1, sizeof(in), fp);
}
balanced_s * b = balanced_enclosures(in);
bool balanced = b->bBal;//If not true, inspect the rest of the
//members to see where the imbalance has occurred.
free(b);
return 0;
}
balanced_s * balanced_enclosures(const char *source)
{
balanced_s *pBal = malloc(sizeof(*pBal));
memset(pBal, 0, sizeof(*pBal));
while(*source)
{
switch(*source) {
case '(':
pBal->paren++;
break;
case ')':
pBal->paren--;
break;
case '{':
pBal->curly++;
break;
case '}':
pBal->curly--;
break;
case '[':
pBal->square++;
break;
case ']':
pBal->square--;
break;
}
source++;
pBal->bBal = (!pBal->paren && !pBal->curly && !pBal->square);
}
return pBal;
}

checking an arrray and returning a bool

I'm in a CS class and I'm trying to create a tic tac toe program. This is my first time using functions and I need help checking a 2d array to see if it is full with 'x' or 'o' s. I initialized to start off with all the elements to '_' and I want a return value of true or false so I'm using #include <stdbool.h>. Here is the function:
bool check_table_full(char board[SIZE][SIZE]){
if(board[0][0] == '_'){
return false;
}else if(board[1][0] == '_'){
return false;
}else if(board[2][0] == '_'){
return false;
}else if(board[0][1] == '_'){
return false;
}else if(board[1][1] == '_'){
return false;
}else if(board[2][1] == '_'){
return false;
}else if(board[0][2] == '_'){
return false;
}else if(board[1][2] == '_'){
return false;
}else if(board[2][2] == '_'){
return false;
}else{
return true;
}
I know there is a better optimization then using if else statement but this is just is simple in my head. I use printf("%s", check_table_full?"true":"false"); to check if it returns false as it should since all elements in the array are '_'. No matter what I do it prints true, and if I change the "true" in the printf statement it prints whatever is inside the first quote.
Everything else works like SIZE is defined, the array is defined, I just can't get this function to return false.
Sorry if this is lengthy, this is my first time asking a question on here.
If you do printf("%s", check_table_full?"true":"false");, you are not calling the function.
check_table_full is the address of the function. You want check_table_full()
You may want to use nested for-loops. I have learned C++ syntax and not C syntax, so the syntax may be a little off.
Example Code...
#include <stdio.h>
int main() {
char board[2][2];
int outer_count, inner_count;
//It will use nested for loops
for (outer_count = 0; outer_count <= 2; count++) {
for (inner_count = 0; inner_count <= 2; count ++) {
if (board[outer_count][inner_count] == '_'){
return false;
}
}
}
return True
}
Your method of traversing the matrix is not scalable, you can easily introduce errors and is unnecessary complex. My 'check method' is 2 lines of code for any matrix size.
#include <stdio.h>
#include <stdbool.h>
#define MXSIZE 3
bool is_full(char *block) {
for (int l=0;l<MXSIZE*MXSIZE;l++)if(*(block+l)=='_')return false;
return true;
}
int main() {
char my2DArray[MXSIZE][MXSIZE]={{'O','O','O'},{'O','O','O'},{'O','O','_'}};
printf("%s",is_full(&my2DArray[0][0])?"The array is full\n":"The array is not full\n");
return 0;
}

Is it normal that void pointers give warnings?

I'm doing a school project and i'm going out of my away to get a better grade
With that being said i'm trying to use void pointers and type casting to make my program as general as possible for any type of scenario i throw at it.
I did some code and it does everything it should do but it gives me some warnings whenever i rebuild all but no warning when i compile it.
Side note: I know i am returning an integer to a pointer, but i can't return an local pointer otherwise it will not give me the result i need.
#define VERDADEIRO 1
#define FALSO 0
void * removido(info* tab,int pos)
{
if(strcmp(tab[pos].nome,REMOVIDO) != 0)
{
return FALSO;
}
else
{
return VERDADEIRO;
}
}
void * vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)!= 0)
{
return FALSO;
}
else
{
return VERDADEIRO;
}
}
int listar(info * tab)
{
int i,c=0,j;
for(i=0;i<HASHTAM;i++)
{
if((int *)removido(tab,i) ==FALSO && (int *)vazio(tab,i)==FALSO)
{
printf("Nome: %s",tab[i].nome);
printf("NIF: %d\n",tab[i].NIF);
printf("Morada: %s",tab[i].morada);
printf("Telefone: %d\n",tab[i].telefone);
printf("Codigo Postal: %d - %d\n",tab[i].codigopostal/1000,tab[i].codigopostal%1000);
printf("Data de nasicmento: %d - %d - %d\n",tab[i].datanascimento%100,(tab[i].datanascimento%10000)/100,tab[i].datanascimento/10000);
printf("Associado: %s\n",tab[i].infoassociado.associado);
if(associado(tab,i)==VERDADEIRO)
{
for(j=0;j<10;j++)
{
printf("Cota de %d anos atras - Estado: %c\n",j+1,tab[i].infoassociado.cotas[j]);
}
}
c++;
}
}
The warnings are comparison between pointer and integer and return makes pointer from integer without a cast.
No, they're not normal. They're telling you that you're using pointers incorrectly. FALSO and VERDADEIRO are not pointers.
Functions which return true and false are not a good use of void pointers, or pointers in general. Nor do you have to define your own true and false values. Instead use the booleans true and false from stdbool.h. (Note: this was added in C99 and some professors cling to the C90 standard.)
#include <stdbool.h>
bool removido(info* tab,int pos)
{
if(strcmp(tab[pos].nome,REMOVIDO) != 0) {
return false;
}
else {
return true;
}
}
bool vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)!= 0) {
return false;
}
else {
return true;
}
}
And then later you can simply check whether the return value is true or false using normal boolean checks.
if( !removido(tab,i) && !vazio(tab,i) ) {
...
}
Note that double negatives make code difficult to understand. If you check for equality and return true, that is simpler.
bool vazio(info* tab,int pos)
{
if(strcmp(tab[pos].nome,CHAVENULA)== 0) {
return true;
}
else {
return false;
}
}
To really simplify the code, you can take advantage that strcmp(...) == 0 returns a boolean (technically it returns 0 or 1 which can be used as a boolean) and reduce those functions to one line.
bool removido(info* tab,int pos)
{
return strcmp(tab[pos].nome,REMOVIDO) == 0;
}

Not able to figure out the logical error in my code

There is some logical error in my code but I'm not able to figure out what it is. When I run my code it doesn't give me desired results.
OUTPUT:
Enter an infix expression
2+3
2
I get 2 as my postfix expression whereas I should be getting 23+.
Please see if anyone could help me out with this one.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<ctype.h>
#define max 20
int top=-1;
char infix[max],postfix[max],stack[max];
char pop();
int empty();
void push(char );
int precedence(char );
void infix_to_postfix(char * ,char * );
void main()
{
clrscr();
printf("Enter an infix expression\n");
gets(infix);
infix_to_postfix(infix,postfix);
printf("%s",postfix);
getch();
}
void infix_to_postfix(char infix[max],char postfix[max])
{
int i=0,j=0;
char value,x;
for(i=0;infix[i]!='\0';i++)
{
value=infix[i];
if(isalnum(value))
{
postfix[j]=value;
j++;
}
else
{
if(value=='(')
push('(');
else
{
if(value==')')
{
while((x=pop())!='(')
{
postfix[j]=x;
j++;
}
}
else
{
while(precedence(value)<=precedence(stack[top])&&!empty())
{
x=pop();
postfix[j]=x;
j++;
}
push(value);
}
}
}
}
while(!empty())
{
x=pop();
postfix[j]=x;
j++;
}
postfix[j]='\0';
}
void push(char x)
{
if(top==max-1)
printf("stack overflow\n");
else
{
top++;
stack[top]=x;
}
}
char pop()
{
char x;
x=stack[top];
top--;
return x;
}
int empty()
{
if(top==-1)
return(0);
return(1);
}
int precedence(char value)
{
if(value=='(')
return(0);
if(value=='+'||value=='-')
return(1);
if(value=='*'||value=='/'||value=='%')
return(2);
return(3);
}
Generally, the logic of your code is OK except a return value mistake in the empty() function.
In the empty(), it should return 1 while stack is empty.
int empty(){
if(top==-1)
return(0); <-- !!! here should return 1
}
Otherwise,
it will go into the while loop at while(precedence(value)<=precedence(stack[top])&&!empty()) even when stack is empty.
And then postfix[j] = x may write a redundant 0(now top= -2) to postfix array.
Finally,under the input 2+3, the postfix[] will be {'2','\0','3','+',...}, which result in the abnormal output 2.
So, it will work after modifying the empty() function, such as
int empty()
{
if(top==-1)
return(1); // not return(0)
return(0);
}
Output:
Enter an infix expression
2+3
23+
all you need to do is change your empty() function
you are checking for !empty() in if condition, but you are returning 0, when it is empty, this will make the condition true, i.e. Stack is not empty. Change the return value to 1 in case of empty stack.

what does return; mean?

The return data-type of a function,whose prototype is declared in main(), is void.
It cointains an instruction return; as in
main()
{
void create(int *p);
*some code*
}
void create(node *list)
{
*some code*
return;
}
What will it return,and where will it return??
It's not going to return anything, you might have return statements in a void function to kind of alter the flow and exit from the function. ie rather than:
void do_something(int i)
{
if (i > 1) {
/* do something */
}
/* otherwise do nothing */
}
you might have:
void do_something(int i)
{
if (i <= 1)
return;
/* if haven't returned, do something */
}
In this case doesn't mean much.
return; means exit suddenly from this function returning void.
int a()
{
return 10;
}
void b()
{
return; // we have nothing to return, this is a void function.
}
void c()
{
// we don't need return; it is optional.
}
return; for a void function is not useful, it can be omitted, is optional.
However sometime it is useful, for example, for exiting a loop or a switch.
void xxx()
{
int i = 0;
while (1)
{
if (++i >= 100)
return; // we exit from the function when we get 100.
}
}
return; won't return anything, which matches the declared void return type of the function create. It will return to the caller of the function it appears in (not shown in your example), just like return EXPRESSION; will.
In this particular piece of code, return; is redundant since it appears at the very end of create, but it's useful when you want to exit a function prematurely:
void print_error(char const *errmsg)
{
if (errmsg == NULL)
// nothing to print
return;
perror(errmsg);
}
it will return from the executing function with a void return value (which means no value).

Resources