Not able to figure out the logical error in my code - c

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.

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;
}

Very Basic Encryption

#include <stdio.h>
int limit;
char alp[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
void encode(char message[21],char enc_message[21],int key);
void decode(char enc_message[21],char dec_message[21],int key);
main()
{
int key,i=0,j=0;
char message[21];
char enc_message[21];
char dec_message[21];
char encrypted[21];
char a='\0';
printf("Input the characters to encrypt\n");
while(i<21 && a!='\n')
{
scanf("%c",&a);
message[i]=a;
i=i+1;
}
for(i=0;;i++) /*custom strlen*/
{
if( message[i]= '\0')
{
limit=i;
break;
}
}
printf("Input the key");
scanf("%d",key);
for(i=0;i<21;i++)
{
enc_message[i]=message[i];
}
encode(message[21],enc_message[21],key);
for(i=0;i<21;i++)
{
dec_message[i]=enc_message[i];
}
for(i=0;i<limit;i++)
{
printf("%c",enc_message[i]);
}
printf("\n\n");
decode(enc_message[21],dec_message[21],key);
for(i=0;i<limit;i++)
{
printf("%c",dec_message[i]);
}
}
void encode(char message[21],char enc_message[21],int key)
{
/*char temp[21];*/
int x,y;
for(x=0;x<limit;x++) /* message check */
{
for(y=0;y<26;y++) /* <----- alphabet check */
{
if (enc_message[x]==alp[y]) enc_message[x]=alp[y+key];
}
}
}
/*------------------------------------------------------------------------*/
void decode(char enc_message[21],char dec_message[21],int key)
{
int x,y;
for (x=0;x<limit;x++)
{
for(y=0;y<26;y++)
{
if (dec_message[x]==alp[y+key]) dec_message[x]=alp[y];
}
}
}
The compiler says,the mistake has to do with the way I call functions(and write them)and says: passing argument1 of 'encode' makes pointer from integer without a cast ,and that is for argument 2 of 'encode' and the exact same for 'decode'
Thanks in advance!
You are passing a single element and it's not even a valid element, try
decode(enc_message, dec_message, key);
Also, format your code so it's readable that is really important, and looping to compute the length of the string to use it in another loop is not a very smart thing, print it in a loop like
for (int i = 0 ; enc_message[i] != '\0' ; ++i) ...
also, don't over use break, just think about the logical condition for the loop, it's the same one where you break. Code is much more readable if the condition appears in the right place.

Undefined reference to function in C Programming

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.

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.

Missing prototype in my practice arithmetic quiz program, and almost every other program I make

Yesterday I was able to make a program (ASCII converter etc etc) that had the same problem [ Every function had a missing prototype error when I build the program ] I was able to fix it through random trial and error having no idea how I did it. Here's my arithmetic quiz practice program. I also tried putting int initialize(),clear(),exit(),additionquiz(),subtractionquiz(),divisionquiz(),multiplicationquiz(); and it still gave me a missing prototype.
#include <stdio.h>
/* Main Menu */
int numbers[10];
int main()
{
while(1==1)
{
int choice;
initialize();
printf("Arithmetic Quiz Program\n");
printf("1 - Addition\n2 - Subtraction\n3 - Multiplication\n4 - Division\n5 - Exit\n");
scanf("%d",&choice);
if(choice==1)
{
clear();
additionquiz();
}
else if(choice==2)
{
clear();
subtractionquiz();
}
else if(choice==3)
{
clear();
multiplicationquiz();
}
else if(choice==4)
{
clear();
divisionquiz();
}
else if(choice==5)
{
exit();
}
else
{
printf("%cPlease choose a number from 1 - 5",7);
clear();
continue;
}
}
return 0;
}
/* For clearing the page */
int clear()
{
int i;
for(i=0;i<25;i++)
{
printf("\n");
}
}
/* Assigns the array */
int initialize()
{
numbers[0]=6;
numbers[1]=0;
numbers[2]=2;
numbers[3]=5;
numbers[4]=3;
numbers[5]=1;
numbers[6]=9;
numbers[7]=4;
numbers[8]=7;
numbers[9]=8;
return 0;
}
/* addition quiz */
int addition()
{
int a,diff,b,answer,choice;
a=0;
diff=1;
b=a+diff;
while(1==1)
{
if(a>9)
{
a=0;
diff++;
}
if(b>9)
{
b=0;
}
if(diff>9)
{
diff=0;
}
printf("%d + %d = ",number[a],number[b]);
scanf("%d",&answer);
if(answer==number[a]+number[b])
{
printf("\nCORRECT!!!\n");
a++;
}
else
{
printf("\nWRONG!!!\n");
clear();
additionquiz();
}
printf("\nWhat do you want to do next?\n1 - Answer another addition Question\n2 - Go back to main menu\n3 - Exit program\n");
scanf("%d",&choice);
if(choice==1)
{
clear();
additionquiz();
}
else if(choice==2)
{
clear();
main();
}
else if(choice==3)
{
exit();
}
else
{
printf("%cPlease choose a number from 1 to 3",7);
}
}
return 0;
}
/* The subtraction quiz */
int subtraction()
{
int a,diff,b,answer,choice;
a=0;
diff=1;
b=a+diff;
while(1==1)
{
if(a>9)
{
a=0;
diff++;
}
if(b>9)
{
b=0;
}
if(diff>9)
{
diff=0;
}
if(numbers[a]-numbers[b]<0)
{
a++;
subtraction();
}
printf("%d - %d = ",numbers[a],numbers[b]);
scanf("%d",&answer);
if(answer==numbers[a]-numbers[b])
{
printf("CORRECT!!!\n\n");
}
else
{
printf("WRONG!!!\n\n");
clear();
subtractionquiz();
}
printf("\nWhat do you want to do next?\n1 - Answer another subtraction Question\n2 - Go back to main menu\n3 - Exit program\n");
scanf("%d",&choice);
if(choice==1)
{
clear();
subtractionquiz();
}
else if(choice==2)
{
clear();
main();
}
else if(choice==3)
{
exit();
}
else
{
printf("%cPlease choose a number from 1 to 3",7);
}
}
return 0;
}
/* multiplication quiz */
int multiplicationquiz()
{
int a,diff,b,answer,choice;
a=0;
diff=1;
b=a+diff;
while(1==1)
{
if(a>9)
{
a=0;
diff++;
}
if(b>9)
{
b=0;
}
if(diff>9)
{
diff=0;
}
printf("%d * %d = ",number[a],number[b]);
scanf("%d",&answer);
if(answer==number[a]*number[b])
{
printf("\nCORRECT!!!\n");
a++;
}
else
{
printf("\nWRONG!!!\n");
clear();
multiplicationquiz();
}
printf("\nWhat do you want to do next?\n1 - Answer another multiplication Question\n2 - Go back to main menu\n3 - Exit program\n");
scanf("%d",&choice);
if(choice==1)
{
clear();
multiplicationquiz();
}
else if(choice==2)
{
clear();
main();
}
else if(choice==3)
{
exit();
}
else
{
printf("%cPlease choose a number from 1 to 3",7);
}
}
return 0;
}
/* Division quiz */
int divisionquiz()
{
int a,diff,b,answer,choice,remain;
a=0;
diff=1;
b=a+diff;
while(1==1)
{
if((numbers[a]<numbers[b])||numbers[b]==0)
{
a++;
clear();
divisionquiz();
}
if(a>9)
{
a=0;
diff++;
}
if(b>9)
{
b=0;
}
if(diff>9)
{
diff=0;
}
printf("%d % %d = \n",numbers[a],numbers[b]);
printf("What is the whole number?\n");
scanf("%d",&answer);
printf("What is the remainder? (0 if none\n)");
scanf("%d",&remain);
if(answer==numbers[a]/numbers[b] && remain==numbers[a]%numbers[b])
{
printf("\nCORRECT!!!");
a++;
}
else
{
printf("\nWRONG!!!");
clear();
divisionquiz();
}
printf("\nWhat do you want to do next?\n1 - Answer another division Question\n2 - Go back to main menu\n3 - Exit program\n");
scanf("%d",&choice);
if(choice==1)
{
clear();
divisionquiz();
}
else if(choice==2)
{
clear();
main();
}
else if(choice==3)
{
exit();
}
else
{
printf("%cPlease choose a number from 1 to 3",7);
}
}
return 0;
}
exit is an external function and you need to include its header at the top of your source code:
#include <stdlib.h> // exit
Please notice that in the function call the addition function is called addition and in the function definition additionquiz. Same for the substraction.
For the other functions, you should declare them before you call them: that is before the main function definition.
int initialize(void);
int clear(void);
int additionquiz(void);
int subtractionquiz(void);
int divisionquiz(void);
int multiplicationquiz(void);
int main(void)
{
/* ... */
Note that declaring all the functions in one go like this:
int initialize(void), clear(void), additionquiz(void),
subtractionquiz(void), divisionquiz(void), multiplicationquiz(void);
is permitted but it is not very readable and may surprise the reader.
Finally, if these functions are not called from another source code, you should tell the reader (and the compiler) by adding a static specifier at the beginning of the declaration like this:
static int clear(void); // the function is only called in this source code
The C compiler works from top-to-bottom. It must know that your functions exist before you attempt to call them. So you have two choices:
Define your functions above main (i.e. move the entire function bodies).
Declare your functions above main. i.e. put int initialize();, etc. above main.
Note also that in C, int initialize() is different to int initialize(void). You should be using the second version.
More information on what the guy above me just said can be found here. This page gives you an overview of how to suppress or enable different kinds of warnings in your code:
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Also another tip. You wrote a couple while loops in your code with this syntax:
while (1==1)
{
...
}
this will do the same thing
while(1)
{
}
Here's why: A while loop, an if statement, else statement, and an else if statement will
all perform the code beneath them if the code inside the parenthesis is true. Since 1 in C is true and 0 is false, my while loop above works the same as yours.
First, learn to compile with all warnings enabled and with debugging information (e.g. with gcc -Wall -g on Linux). Then improve your program till no warnings are given by the compiler (trust the compiler).
Then, learn to have a declaration for each of your function. Start your sole source file with them, or, if you have several source files, make a header file with them.
So you could add just after your #include lines:
// clear the screen
void clear(void);
// initialize the numbers
int initilize(void);
// addition quiz
int addition(void);
// subtraction quiz
int subtraction(void);
// multiplication quiz
int multiplicationquiz(void);
// division quiz
int divisionquiz(void);
By the way, your functions might be better named, and you could have formal arguments in them (else use void as the argument list). And I don't understand why they all return an int which you don't use.

Resources