Undefined reference to function in C Programming - c

Undefined reference to All Functions as "push , pop ,createstack, etc.."
I included all the header files correctly , but when I run it I get the error: undefined reference to '(function name)'. I get this error for all my functions.
Below you can find the source code of all my three files.
Test.c
#include <stdio.h>
#include "Stack.h"
void printMessage() {
printf("\n(a) Read an element then Push it.\n");
printf("(b) Pop an element then display it.\n");
printf("(c) Returns a copy of the top-element of the stack without deleting it\n");
printf("(d) Exit.\n");
}
void userStackTop(Stack *ps, StackEntry *pe) {
pop(ps, pe);
push(ps, *pe);
}
Stack S;
StackEntry E;
int Size;
char Choice;
int main() {
setvbuf(stdout, NULL, _IONBF, 0); //Eclipse Bug for scanf and printf
createStack(&S);
printf("Welcome: ");
printMessage();
while (scanf("\n%c", &Choice)) {
if (Choice == 'a' || Choice == 'A') {
printf("Enter Your Element: ");
scanf("\n%c", &E);
if (!stackFull(&S)) {
push(&S, E);
printf("Element (%c) is pushed into stack.\n\n",E);
}
else
printf("\n\nSorry , The Stack is Full!\n\n");
} else if (Choice == 'b' || Choice == 'B') {
if (!stackEmpty(&S)) {
pop(&S, &E);
printf("\n\nThe Element (%c) is popped.\n\n", E);
} else
printf("\n\nSorry , The Stack is Empty!\n\n");
} else if (Choice == 'c' || Choice == 'C') {
if (!stackEmpty(&S)) {
//stackTop(&S, &E);
userStackTop(&S, &E);
printf("Last Element Pushed in the stack is (%c).\n",E);
} else
printf("\n\nSorry , The Stack is Empty!\n\n");
} else if (Choice == 'd' || Choice == 'D')
return 0;
printMessage();
}
return 0;
}
Stack.c
#include "Stack.h"
void createStack(Stack *ps) {
ps->top = 0;
}
void push(Stack *ps, StackEntry e) {
ps->Data[ps->top++] = e;
}
void pop(Stack *ps, StackEntry *pe) {
*pe = ps->Data[ps->top - 1];
ps->top--;
}
int stackEmpty(Stack *ps) {
if (ps->top <= 0)
return 1;
else
return 0;
}
int stackFull(Stack *ps) {
if (ps->top == MAXSTACK - 1)
return 1;
else
return 0;
}
int stackSize(Stack *ps) {
return ps->top + 1;
}
void stackTop(Stack *ps, StackEntry *pe) {
*pe = ps->Data[ps->top-1];
}
Stack.h
#ifndef STACK_H_
#define STACK_H_
typedef char StackEntry;
#define MAXSTACK 10
typedef struct stack {
int top;
StackEntry Data[MAXSTACK];
} Stack;
void createStack(Stack *ps);
void push(Stack *ps, StackEntry e);
void pop(Stack *ps, StackEntry *pe);
int stackEmpty(Stack *ps);
int stackFull(Stack *ps);
int stackSize(Stack *ps);
void stackTop(Stack *ps, StackEntry *pe);
#endif /* STACK_H_ */

Somewhat surprisingly maybe, the problem is in your file names...
Unless you tell the compiler otherwise, a .C (upper case) file is taken to mean a C++ file, and .c (lower case) to mean a C file. If you mix them, the object files that the compiler produces are not "compatible".
You are mixing both (Test.C and Stack.c), so the linker will not find the functions that are used in Main.obj in Test.obj and will issue an unresolved external symbol error. (The linker cannot find the corresponding functions because of name mangling differences between C and C++.)
One solution is to rename Test.C to Test.c.

Related

Trying to write a program that ask the user to input parentheses and brackets. The program will then tell the users whether they are properly nested

As the title states I am trying to write a program that will tell the user if there inputted brackets and or parentheses are properly nested. Here is my code.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 100
char contents[STACK_SIZE];
int top = 0;
void stack_overflow();
void stack_underflow();
void make_empty(void)
{
top = 0;
}
bool is_empty(void)
{
return top == 0;
}
bool is_full (void)
{
return top == STACK_SIZE;
}
void push(char i)
{
if (is_full())
stack_overflow();
else
contents[top++] = i;
}
char pop(void)
{
if (is_empty())
stack_underflow();
else
return contents[--top];
}
int main(void)
{
char input;
bool is_nested=true;
printf("Enter parentheses and/or braces: ");
while ((input = getchar()) != '\n')
{
if(input =='(' || input == '{')
push(input);
if(input ==')' && pop() != '(')
is_nested = false;
if(input =='}' && pop() != '{')
is_nested = false;
}
if (is_empty() == false) is_nested = false;
if (is_nested)
printf("Parentheses/braces are nested properly");
else
printf("Parentheses/braces are not nested properly");
return 0;
}
When I compile the code I keep getting the error:
C:\Users\g\AppData\Local\Temp\ccy6YhqI.o:brackets.c:(.text+0x45): undefined reference to `stack_overflow'
C:\Users\g\AppData\Local\Temp\ccy6YhqI.o:brackets.c:(.text+0x76): undefined reference to `stack_underflow'
collect2.exe: error: ld returned 1 exit status
I cannot seem to find why I am getting this error. Any help would be appreciated.
clearly you haven't implemented stack_overflow() nor stack_underflow().
void foo(); is not a sufficient function definition.

conflicting types and no return

Hello I am doing a program of the kind of a quiz but it is giving me two error one and in "error: conflicting types for 'Pergunta2'" and the other error is in Return I want the user to choose between "M" and "F" but in the structure store "masculino" or "feminino" but isn’t someone doing it who can help me? Thank you.
int main()
{
questionario();
}
void questionario()
{
int numero = 0;
struct pessoas{
int numero_questionario, idade;
char sexo;
}QUESTIONARIO[MAXQUESTIONARIO];
QUESTIONARIO[0].numero_questionario = numero++;
QUESTIONARIO[0].idade = pergunta1();
QUESTIONARIO[0].sexo = pergunta2();
printf("\nnunmero do questionario:%d, idade:%d, sexo:%c ", QUESTIONARIO[0].numero_questionario, QUESTIONARIO[0].idade, QUESTIONARIO[0].sexo);
}
int pergunta1()
{
int resposta;
printf("\nPergunta 1 - Idade do participante?");
printf("\nResposta - ");
scanf("%d", &resposta);
if(resposta < 18)
{
do{
printf("\nTem que ser maior de idade.");
printf("\nResposta - ");
scanf("%d", &resposta);
}while(resposta < 18);
}
return resposta;
}
char pergunta2()
{
char resposta;
printf("\nPergunta 2 - Genero");
printf("\n (M)asculino");
printf("\n (F)eminino");
do{
printf("\nResposta - ");
scanf("%s", &resposta);
}while(resposta !='M' && resposta !='m' && resposta !='F' && resposta !='f');
if(resposta == 'M' || resposta == 'm')
{
resposta = 'masculino';
}else if(resposta == 'F' || resposta == 'f')
{
resposta = 'femenino';
}
return resposta;
}
If you don't declare a function before it's used, the compiler will make an "implicit declaration" that the function takes no arguments and returns an int. Then your explicit declaration of void questionario() conflicts with the implicit declaration int questionario().
int main()
{
// implicit declaration `int questionario()`.
questionario();
}
// conflicting explicit declaration for `questionario`
void questionario()
{
...
}
You can fix this by reordering the function declarations so they are declared before they are used.
void questionario()
{
...
}
int main()
{
questionario();
}
Sometimes this is not possible. Then use a forward declaration which repeats the function signature. Remember to change both.
void questionario();
int main()
{
questionario();
}
void questionario()
{
...
}

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.

I'm facing a runtime error in a c program that should convert from infix to postfix notation

I'm writing a program that should read equations from a txt file and fill them in a linked-list, check their validity and then convert each valid equation to post-fix notation and calculate the final result. Then write them to a file or print them on the console depends on the user choice. Following is what I've already done, I know my code is really long but I posted it all in order to make my question more clear:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node *ptr;
struct node
{
char eq[100];
char pstfix[100];
double result;
ptr next;
int topPST;
int topOP;
int validity;
};
typedef ptr list;
typedef ptr position;
list l;
void menu(); // prints the menu
void readFile(list l); //reads data from a file
int opPriority(char operators[],char operation,int top) ; // check the priority of a given operation
void isValid(position p);//Function to check the validity of each equation.
void convert(list l); // to convert from infix to postfix
void getResult(list l); // to calculate the result of an equation
double calculate(char operation, int op1,int op2);//To return the value in each step when getting the result
void showValidity(list l); // print the equations and show the ones that have errors
void acceptEq(list l); // Let the user enter equations on the console screen
void fillInfix(position p, char c[]);//A function to fill the array of infix in the node.
int isNum(char val);//returns if the value passed to it is a number or character.
void writeToFile(list l);//Write to the file
void showConsole(list l);//Show the final results on the console
int main()
{
printf("\t\t\t*Data Structure\tSecond project*\n\n\t\t\t*Convert from infix to postfix*\n\n");
menu();
l=(list)malloc(sizeof(struct node));
return 0;
}
//Function to print the menu and let the program work depending on the choice.
void menu()
{
system("cls");
int choice;
printf("\t\t\t\tMenu\n\n\t\t\t1.Read equations from file.\n\t\t\t2.Check validity.\n\t\t\t3.Convert to postfix.\n\t\t\t4.Add more equations to the file.\n\t\t\t\n\t\t\t5.Calculate Results.\n\t\t\t6.Write results to file.\n\t\t\t7.Show results on the console.\n\t\t\t8.End.\n\n\t\t\tEnter Your choice number please\n\t\t\t");
scanf("%d",&choice);
switch (choice)
{
case 1: readFile(l);
break;
case 2: isValid(l);
break;
case 3: convert(l);
break;
case 4: acceptEq(l);
break;
case 5: getResult(l);
break;
case 6: writeToFile(l);
break;
case 7: showConsole(l);
break;
case 8: exit(0);
}
}
//The following function should read equations from a file specified by the user
void readFile(list l)
{
system("cls");
char fileName[50];
FILE *eqFile;
printf("\t\t\tEnter the title of the file please\n\t\t\t");
scanf("\t\t\t%s",fileName);
eqFile=fopen(fileName,"r");
//To ensure the existence of the requested file.
while (eqFile == NULL)
{
printf("\t\t\tThe file you asked for does not exist. Enter another name or enter 'back' to return to menu\n\t\t\t");
scanf("\t\t\t%s",fileName);
if(strcmp(fileName,"back")==0) menu();
else eqFile=fopen(fileName,"r");
}
(l)->next=(position)malloc(sizeof (struct node));
position temp=(l)->next;
char line[100];
while (temp != NULL){
while (fgets(line,sizeof line, eqFile) != NULL)
{
isValid(temp);
if ((temp)->validity) fillInfix(temp,line);
temp=(temp)->next;
(temp)->next=NULL;
}
}
fclose(eqFile);
int choice;
printf("\t\t\tData Read Successfully\n\t\t\tEnter 0 to exit or 1 to return to menu\n\t\t\t");
scanf("%d",&choice);
if (choice) menu();
else exit(0);
}
void isValid(list l)
{
system("cls");
position temp;
temp=l;
int i,count=0;
while((temp)->next!=NULL)
{
for (i=0;i<100;i++)
{
if (((l)->eq[i]=='+' && (l)->eq[i+1]=='*') || ((l)->eq[i]=='-' && (l)->eq[i+1]=='*')|| ((l)->eq[i]=='*' && (l)->eq[i+1]=='/') || ((l)->eq[i]=='/' && (l)->eq[i+1]=='+')|| ((l)->eq[i]=='/' && (l)->eq[i+1]=='-') || (l)->eq[i]==' ')
count++;
}
if (count!=0) (temp)->validity=0;
temp=(temp)->next;
}
int choice;
printf("\t\t\tChecking validity is done enter 0 to quite or 1 to return to menu\n\t\t\t");
scanf("%d",&choice);
if(choice) menu();
else exit(0);
}
void fillInfix(position p, char line[])
{
int i;
for (i=0;i<100;i++)
{
while (line[i]!='\0')
{
(p)->eq[i]=line[i];
}
}
}
void push(char st[],char element, int top)
{
++top;
st[top]=element;
}
char pop(char st[],int top)
{
char elemnt=st[top];
--top;
return elemnt;
}
int opPriority(char operators[], char operation, int top)
{
if ((operation=='*' && operators[top]=='-') || (operation=='*' && operators[top]=='+') || (operation=='*' && operators[top]=='/') || (operation=='/' && operators[top]=='-')|| (operation=='/' && operators[top]=='+') || (operation=='+' && operators[top]=='-')) return 0;
else
if ((operation=='(' && operators[top]=='*') || (operation=='(' && operators[top]=='/') || (operation=='(' && operators[top]=='+') || (operation=='(' && operators[top]=='-')) return 0;
else if (operation==')') return 2;
else
return 1;
}
int isNum(char val)
{
if (val!='+' && val!='-' && val!='*' && val!='/') return 1;
else return 0;
}
void convert(list l)
{
position temp=l;
int i;
char operators[100];
while ((temp)->next != NULL)
{
temp=(temp)->next;
if ((temp)->validity)
{
for (i=0;i<100;i++)
{
if (isNum((temp)->eq[i])) push((temp)->pstfix,(temp)->eq[i],(temp)->topPST);
else
{
int priority=opPriority(operators,(temp)->eq[i],(temp)->topOP);
if (priority==1)
{
push((temp)->pstfix,pop(operators,(temp)->topOP),(temp)->topPST);
push(operators,(temp)->eq[i],(temp)->topOP);
}
else
if (priority ==0) push(operators,(temp)->eq[i],(temp)->topOP);
else
if (priority==2)
{
while (operators[(temp)->topOP]!='(')
{
push((temp)->pstfix,pop(operators,(temp)->topOP),(temp)->topPST);
}
char trash=pop(operators,(temp)->topOP);//Unwanted closed bracket
}
}
}
}
}
int choice;
printf("\t\t\tConversion Done successfully. Enter 0 to quite or 1 to return to menu\n\t\t\t");
scanf("%d",&choice);
if(choice) menu();
else exit(0);
}
void acceptEq(list l)
{
system("cls");
char newEq[100];
printf("\t\t\t Enter your equation please. Note that your equation must not exceed the 100 characters length.\n\t\t\t");
scanf("\t\t\t%s",newEq);
position temp=l;
position p=(position)malloc(sizeof (struct node));
while ((temp)->next!=NULL)
{
temp=(temp)->next;
}
(temp)->next=p;
isValid(p);
if ((p)->validity)
{
fillInfix(p,newEq);
convert(p);
}
}
void getResult(list l)
{
system("cls");
position temp=l;
while ((temp)->next != NULL)
{
temp=(temp)->next;
int i=0;
while ((temp)->pstfix[i]!= '\0')
{
if ((temp)->pstfix[i]=='+' || (temp)->pstfix[i]=='-' || (temp)->pstfix[i]=='*' || (temp)->pstfix[i]=='/')
(temp)->result = calculate((temp)->pstfix[i],(temp)->pstfix[i-2],(temp)->pstfix[i-1]);
push((temp)->pstfix,(temp)->result,(temp)->topPST);
printf("\n\t\t\t%c",(temp)->pstfix[i]);
i++;
}
printf("=%f",(temp)->result);
}
}
double calculate (char operation,int op1,int op2)
{
double result;
if (operation=='+') result=op1+op2;
if (operation=='-') result=op1-op2;
if (operation=='*') result=op1*op2;
if (operation=='/') result=op1/op2;
return result;
}
void writeToFile(list l)
{
system("cls");
char fileWName[50];
printf("\n\t\t\tEnter the name of the file you want to print on please\n\t\t\t");
scanf("\t\t\t%s",fileWName);
FILE* resultFile;
resultFile=fopen(fileWName,"w");
position temp=l;
fprintf(resultFile,"Infix Notation:\t\t");
fprintf(resultFile,"Validity:\t\t");
fprintf(resultFile,"Postfix Notation:\t\t");
fprintf(resultFile,"Value:\t\t\n");
while ((temp)->next != NULL)
{
temp=(temp)->next;
int i=0;
while ((temp)->eq[i]!='/0')
{
fprintf(resultFile,"%c",(temp)->eq[i]);
i++;
}
fprintf(resultFile,"\t\t");
i=0;
while ((temp)->pstfix[i]!='/0')
{
fprintf(resultFile,"%c",(temp)->pstfix[i]);
i++;
}
fprintf(resultFile,"\t\t");
if ((temp)->validity == 0) fprintf(resultFile,"INVALID");
else
{
fprintf(resultFile,"VALID\t\t");
fprintf(resultFile,"%f",(temp)->result);
}
}
fclose(resultFile);
int choice;
printf("\t\t\tDATA WRITTEN TO FILE SUCCESSFULLY. Press 1 to return to menu or 0 to quite\n\t\t\t");
scanf("%d",&choice);
if (choice) menu(l);
else exit(0);
}
void showConsole(list l)
{
system("cls");
position temp=l;
printf("Infix Notation:\t\t");
printf("Validity:\t\t");
printf("Postfix Notation:\t\t");
printf("Value:\t\t\n");
while ((temp)->next != NULL)
{
temp=(temp)->next;
int i=0;
while ((temp)->eq[i]!='/0')
{
printf("%c",(temp)->eq[i]);
i++;
}
printf("\t\t");
i=0;
while ((temp)->pstfix[i]!='/0')
{
printf("%c",(temp)->pstfix[i]);
i++;
}
printf("\t\t");
if ((temp)->validity == 0) printf("INVALID");
else
{
printf("VALID\t\t");
printf("%f",(temp)->result);
}
}
int choice;
printf("\t\t\tDATA WRITTEN SUCCESSFULLY. Press 1 to return to menu or 0 to quite\n\t\t\t");
scanf("%d",&choice);
if (choice) menu();
else exit(0);
}
I've already used debugger to find out where my problem is. And now I know that there's a compiling error in this statement:
(l)->next=(position)malloc(sizeof (struct node));
I'm wondering what's wrong with this statement? I'm trying to allocate space for a node in order to be able to create more nodes for each line (equation).
In this case it's easy to see what's wrong: You try to dereference a NULL pointer.
To understand why, you should know that all global variables, like the variable l in your program, are zero-initialized. That basically means that the pointer l is initialized to NULL.
The problem arise because memory for l is not allocated until after you call the menu function. So any function called from menu will have l equal NULL.
There are a few other problems with your code. One is that memory you allocate with malloc is not initialized at all, so for example when you later in the readFile function call isValid with the newly allocated node, and in isValid dereference the temp->next pointer, the value of that next pointer is indeterminate (and in reality will be seemingly random). Accessing uninitialized data like that will lead to undefined behavior. This of course goes for all data inside the structure, not just pointers.
You also don't seem to set temp->validity to non-zero anywhere.

including header file in two .c files

The program should save a couple of points and put them out on request.
The program contains one .h file and two .c files.
This is the compiler info i get:
prog.c:46:25: fatal error: pointstack.h: No such file or directory #include "pointstack.h"
What did I miss?
//File: pointStack.h - Headerfile
#ifndef POINTSTACK_H
#define POINTSTACK_H
#include <stdio.h>
#include <stdlib.h>
//structs
//struct for coordinates
struct point
{
float rX;
float rY;
float rZ;
};
typedef struct point POINT;
struct stackPoint
{
POINT p;
struct stackPoint *next;
};
typedef struct stackPoint STACK_POINT;
typedef STACK_POINT *STACK_POINT_PTR;
//functions
void push(POINT pushPoint);
POINT pop();
int isEmpty();
void printStackElement(POINT aPoint);
#endif
//File: pointstack.c - functions of stack program
#include "pointstack.h"
//global variable
STACK_POINT_PTR stackTop = NULL;
void push(POINT pushPoint)
{
//temporary variable
STACK_POINT_PTR stackPoint = (STACK_POINT_PTR) malloc(sizeof(STACK_POINT));
//in case there is not enough memory
if(stackPoint == NULL)
{
printf("not enough memory ... End \n");
exit(1);
}
//save point
stackPoint->p = pushPoint;
stackPoint->next = stackTop;
stackTop = stackPoint;
return;
}
POINT pop()
{
//save stackTop and nextStackTop
STACK_POINT firstStackPoint = *stackTop;
free(stackTop);
stackTop = firstStackPoint.next;
return firstStackPoint.p;
}
int isEmpty()
{
if(stackTop == NULL)
{
return 1;
}
else {
return 0;
}
}
void printStackElement(POINT aPoint)
{
printf("Point x: %f, Point y: %f, Point z: %f \n", aPoint.rX, aPoint.rY, aPoint.rZ);
return;
}
//File: stackmain.c
#include "pointstack.h"
void exit(int);
POINT readPoint()
{
POINT userPoint;
printf("x-coordinate \n");
scanf("%62f", &userPoint.rX);
printf("y-coordinate \n");
scanf("%62f", &userPoint.rY);
printf("z-coordinate \n");
scanf("%62f", &userPoint.rZ);
return userPoint;
}
int main(void)
{
//declaration
char cCmd;
printf("’p’ for input, ’q’ for output: \n");
while(1)
{
scanf("%c", &cCmd);
if(cCmd == 'p')
{
push(readPoint());
printf("’p’ for input, ’q’ for output: \n");
}
if(cCmd == 'q')
{
while(!isEmpty())
{
printStackElement(pop());
}
break;
}
}
return 0;
}
What you missed is that your file is called pointStack.h with a capital S, not pointstack.h with a lower case s.

Resources