For my programming class I have to program a calculator that functions with a stack.
Here's the code I made for the stack itself:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
double stk[MAXSIZE]; //Stack array
int top=-1; //Top position in stack
void push(double n);
double pop(void);
void display(void);
/* Add an element to the stack */
void push(double n) {
if (top == (MAXSIZE - 1)) {
printf ("Stack is full\n");
}
else {
//s.top++;
//stk = (double *) malloc(MAXSIZE*sizeof(double));
stk[++top] = n;
}
return;
}
/* Remove and return the top element from the stack */
double pop() {
double num;
if (top == -1) {
printf ("Stack is empty\n");
return (top);
}
else {
num = stk[top--];
printf ("Pop:%f\n", num); //Debugging line
return (num);
}
}
/* Prints all elements in the stack */
void display() {
int i;
if (top == -1) {
printf ("Stack is empty\n");
return;
}
else {
for (i = top; i >= 0; i--) {
printf ("%f\n", stk[i]);
}
}
}
And this is the the calculator (which is in a different file, I'm using makefile to compile):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int isNumber(const char *s);
void insert(double num);
void sum(void);
int main(int argc, char *argv[]) {
int loop = 1;
char input[10];
/* Main Loop */
while (loop == 1) {
printf("> ");
scanf(" %[^\n]", input);
if (isNumber(input)) {
double nu = atof(input);
insert(nu);
}
else if (strcmp(input, "+") == 0)
sum();
else if (strcmp(input, "l") == 0)
list();
else if (strcmp(input, "exit") == 0) //exit
loop = 0;
} //end while
} //end main
int isNumber(const char *s) {
while (*s) {
if((*s<'0' || *s>'9') && *s!='-' && *s!='.')
return 0;
s++;
}
return 1;
}
void insert(double num) {
push(num);
}
/* This function is called when the user enters a '+' instead of a number into the command line. It takes the top two numbers from the stack and adds them together */
void sum() {
double num1, num2, res;
num1 = pop();
num2 = pop();
res = num1+num2;
printf("num1:%f num2:%f sum:%f\n", num1, num2, res); //Debug
}
int list() {
display();
}
The program compiles fine. When I run it I test it by entering a 5 followed by a 6 followed by a + and I get this output:
Pop:6.000000
Pop:4.000000
num1:13.000000 num2:13.000000 sum:26.000000
So apparently the number that the pop() function returns is correct but when assigning it to variables in the calculator function it changes it into a 13 for some reason. It's not always 13, for larger numbers it's higher; entering 500 returns 14, 1000 returns 15, 10000 returns 16 and so on.
I initially made my stack with a array of ints and it actually worked perfectly (it still does if I change all the doubles to ints). Also the stack itself seems to be working fine since the display() function correctly prints all the values the user entered).
I'm really confused as to where the error is coming from and I'm actually thinking of rewriting the whole stack as a linked list instead but I wanted to give this a last shot.
Thanks in advance for your help.
EDIT: I added an #include "Stack.h" (Changed Stack.c to Stack.h) in my calculator file and disposed of the makefile and it now works. I have no idea what was happening originally but I'm just glad it works.
I put all your logic in one file, and add simple main:
int main()
{
push(4.0);
push(3.8);
sum();
return 0;
}
Then compile all as gcc main.c. And it works fine:
Pop:3.800000
Pop:4.000000
num1:3.800000 num2:4.000000 sum:7.800000
Are you sure that you really normally link your project (and break your code to some modules)? Can you put more information about how you compile your version?
P.S. You have all good in program logic
Update
You need to add Stack.h file with the same text:
#include <stdio.h>
#include <stdlib.h>
void push(double n);
double pop(void);
void display(void);
In Stack.c remove this code and add #include "Stack.h" in the first line.
In Main.c only add #include "Stack.h" in the 6 line (just after system #include directives).
Don't change your makefile. It's not required.
With regards,
AJIOB
Related
I'm trying to create a stack in C using structures but the push() function I wrote is acting strangely. I'm sure it is something obvious that I'm missing but I just couldn't figure out what.
#include <stdio.h>
#define STACK_SIZE 50
typedef struct stack
{
int top;
int items[STACK_SIZE];
}
STACK;
void push(STACK* st, int newitem)
{
st->top++;
st->items[st->top] = newitem;
printf("%d", st->items[st->top]);
}
int main()
{
int n = 1;
STACK* st;
printf("test 1\n");
st->top = -1;
push(st, n);
printf("test 2\n");
return 0;
}
DevCpp only compiles but doesn't execute the code. OnlineGDB runs it but only prints the first test.
This is because your variable STACK* st; was never initialized properly.
Some Important Points:
Don't assign -1 to the length (top), 0 would be better
STACK* st; should be just STACK st;
Your function void push(STACK* st, int newitem) should be declared with static linkage.
Write st->top++
Pass st variable by address to the push() function
Instead of using bare return 0;, use return EXIT_SUCCESS;, which is defined in the header file stdlib.h.
As your total STACK_SIZE is only 50 so, int will be sufficient. But as your STACK_SIZE grows use size_t for your length(top).
use int main(void) { }, instead of int main() { }
NOTE: If STACK_SIZE and top becomes equal means your array is filled completely then further addition of data will lead to Undefined Behavior.
Final Code
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 50
typedef struct stack
{
int top;
int items[STACK_SIZE];
}
STACK;
static void push(STACK* st, int newitem)
{
if(st->top == STACK_SIZE)
{
fprintf(stderr, "stack size reached maximum length\n");
exit(EXIT_FAILURE);
}
st->items[st->top++] = newitem;
printf("%d\n", st->items[st->top - 1]); // we added +1 to `top` in the above line
}
int main(void)
{
int n = 1;
STACK st;
printf("test 1\n");
st.top = 0;
push(&st, n); //pass by address
return EXIT_SUCCESS;
}
I am trying to add more than one string to a string in a struct and when I get to the line "fgets" the program just crashes/closes. If someone knows what the problem is in my code, I will very much appreciate that.
I was debugging the code and the problem is in the function "addReason" in the line of "fgets" but I didn't understand what exactly the problem.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PRO_OP 1
#define CON_OP 2
#define PRINT_OP 3
#define EXIT_OP 4
#define STR_LEN 50
#define MAX_LIST_LENGTH 10
typedef struct reasonList
{
char* listName;
char* reasons[MAX_LIST_LENGTH];
int numReasons;
} reasonList;
void initList(reasonList* list, char* name);
void addReason(reasonList* list);
void printList(reasonList* list);
int menu(void);
void myFgets(char str[], int n);
void deleteList(reasonList* list);
int main(void)
{
char dillema[STR_LEN] = { 0 };
int op = 0;
reasonList proList;
initList(&proList, "PRO");
reasonList conList;
initList(&conList, "CON");
printf("What is your dillema?\n");
myFgets(dillema, STR_LEN);
while (op != EXIT_OP)
{
op = menu();
switch (op)
{
case(PRO_OP):
addReason(&proList);
break;
case(CON_OP):
addReason(&conList);
break;
case(PRINT_OP):
printf("Your dillema:\n");
printf("%s\n\n", dillema);
printList(&proList);
printList(&conList);
break;
case(EXIT_OP):
deleteList(&proList);
deleteList(&conList);
break;
}
}
printf("Good luck!\n");
getchar();
return 0;
}
/*
Function will add a reason to the list
input: the list to add to and its name
output: none
*/
void addReason(reasonList* list)
{
printf("Enter a resone to add to list %s:\n", list->listName);
fgets(list->reasons[list->numReasons], STR_LEN, stdin);
list->reasons[strcspn(list->reasons[list->numReasons], '\n')] = '\0';
list->numReasons++;
}
You have to allocate buffer and assign that before reading strings.
void addReason(reasonList* list)
{
printf("Enter a resone to add to list %s:\n", list->listName);
list->reasons[list->numReasons] = malloc(STR_LEN); /* allocate buffer */
if (list->reasons[list->numReasons] == NULL) return; /* check if allocation succeeded */
fgets(list->reasons[list->numReasons], STR_LEN, stdin);
list->reasons[strcspn(list->reasons[list->numReasons], '\n')] = '\0';
list->numReasons++;
}
I am trying to code the printf function. The problem is that my code is getting very messy and I need some help to try to make it organized and working (hopefully). I have been told that I should use "array of function pointers" so I tried below (ft_print_it) as you can see but I do not know how to how to structure my code so that I can use a big array of function pointer to put every function like int_decimal_octal and friends. Can you help me on that? Where can I call them from?
Also, I realized the little function below (cast_in_short) is giving me the same result as printf if I write the output with my ft_putnbr. My second question is thus: Can I make my printf work with little functions like this? Thank you so much.
int cast_in_short(int truc)
{
truc = (short)truc;
return (truc);
}
/*
here in the main I noticed that I get the same behaviour
between my putnbr and printf thanks to my little function
cast_in_short. This is the kind of function I want to use
and put into an array of pointer of functions in order
to make my printf work
*/
int main()
{
int n = 32769;
n = cast_in_short(n);
ft_putnbr(n);
printf("\n");
return (0);
}
/* function to launch ft_print_it */
int ft_print_str_spec(va_list ap, char *flag)
{
if (ft_strlen(flag) == 1)
ft_putstr(va_arg(ap, char *));
else
{
ft_nbzero(ap, flag, 0);
ft_putstr(va_arg(ap, char *));
}
return (1);
}
int ft_print_oct(va_list ap, char *flag)
{
if (ft_strlen(flag) == 1)
ft_putnbr(decimal_octal((va_arg(ap, int))));
else
{
ft_nbzero(ap, flag, 1);
ft_putnbr(decimal_octal((va_arg(ap, int))));
}
return (1);
}
#include "libft.h"
#include <stdarg.h>
#include <stdio.h>
char *ft_strjoin2(char const *s1, char const c);
#include "libft.h"
#include <stdarg.h>
#include <stdio.h>
int decimal_octal(int n) /* Function to convert decimal to octal */
{
int rem;
int i;
int octal;
i = 1;
octal = 0;
while (n != 0)
{
rem = n % 8;
n /= 8;
octal += rem * i;
i *= 10;
}
return (octal);
}
I think the best way to organize your code to avoid the function like your "flag_code" is to use an array of structure. With structure that contain a char (corresponding to the flag) and a function pointer.
For example :
typedef struct fptr
{
char op;
int (*ptr)(va_list);
} fptr;
And instatiate it like that (with { 'flag', name of the corresponding function} ) :
fptr fptrs[]=
{
{ 's', ft_print_nb_spec },
{ 'S', ft_print_nb_up },
{ 0, NULL }
};
Then when you know have char after the % (the flag) you can do something like this :
int i = -1;
while (fptrs[++i].op != flag && fptrs[i].op != 0);
if (fptrs[i].op != 0)
{
fptrs[i].ptr();
}
For exemple if flag = 'S' the while loop will stop when i = 1 and when you call fptrs[1].ptr() you will call the corresponding function in the structure.
I think instead of making your code messy by using function pointers, because in the end you cannot specialize printf function without providing the format, in C there is no function overloading or template functions. My suggestion is to special printf function by type.
// print seperator
void p (int end)
{ printf(end?"\n":" "); }
// print decimal
void pi (long long n)
{ printf("%lld",n); }
// print unsigned
void pu (unsigned long long n)
{ printf("%llu",n); }
// print floating point
void pf (double n)
{ printf("%g",n); }
// print char
void pc (char n)
{ printf("%c",n); }
// print string
void ps (char* n)
{ printf("%s",n); }
Test try here
pi(999),p(0),pf(3.16),p(0),ps("test"),p(1);
Output
999 3.16 test
Another option
In theory you can define polymorphic print function in a struct, in case you can do something like this. I haven't tested this yet.
struct Node
{
enum NodeType {Long,Double,Char,String} type;
union {long l,double d,char c,char* s};
};
void p(Node* n)
{
switch (n->type)
{
case Node::NodeType::Long: printf("%ld", n->l);
case Node::NodeType::Double: printf("%g",n->d);
case Node::NodeType::Char: printf("%c",n->c);
case Node::NodeType::String: printf("%s",n->s);
}
}
I have this "simple" problem: I have in input 2 int numbers and i must output them in decreasing order.
#include <stdio.h>
#include <iostream>
int fnum()
{
int NUM;
scanf("%d",&NUM);
return NUM;
}
void frisultato(int x,int y)
{
if (x>y)
{
printf("%d",x);
printf("%d",y);
}
else
{
printf("%d",y);
printf("%d",x);
}
return;
}
int main()
{
int A,B;
A=fnum;
B=fnum;
frisultato(A,B);
}
I recieve an error at
A=fnum;
B=fnum;
my compiler says: invalid conversion from int(*)() to int.
This is the first time i use functions, what is the problem? Thank you!
Michelangelo.
A=fnum;
B=fnum;
You're not actually calling the function fnum here. You're attempting to assign a pointer to the function to the int variables A and B.
To call the function, do this:
A=fnum();
B=fnum();
Sorry, but since you seem to be new at programming, I couldn't help but refactor/comment on your code:
#include <stdio.h>
#include <iostream>
int fnum()
{
int num;
scanf("%d",&num);
return num;
}
void frisultato(int x, int y)
{
if (x>y)
{
printf("%d",x);
printf("%d",y);
}
else
{
printf("%d",y);
printf("%d",x);
}
/* No need to return in void */
}
int main()
{
/*
Variables in C are all lowercase.
UPPER_CASE is usually used for macros and preprocessor directives
such as
#define PI 3.14
*/
int a, b;
a = fnum(); //Function calls always need parenthesis, even if they are empty
b = fnum();
frisultato(a, b);
/*
Your main function should return an integer letting whoever
ran it know if it was successful or not.
0 means everything went well, anything else means something went wrong.
*/
return 0;
}
Also, don't sign your name on StackOverflow questions.
I bought a Programming book at a yard sale for $2 because I've always wanted to learn how to code but don't have the money and resources for school. I've gotten through the first few chapters just fine, but I've also had the solutions to the problems I was working on. But the chapter is missing a few of the pages after the chapter summary when they start listing problems. I was wondering if you guys could help me out.
Here is the problem. Note: Needs to use a recursive function.
#include <stdio.h>
#include <stdlib.h>
void binaryPrinter(int value, int *numberOfOnes);
void print(char c);
//You do not need to modify any code in main
int main()
{
char value;
int result = 1;
while(result != EOF)
{
result = scanf("%c",&value);
if(result != EOF && value != '\n')
{
print(value);
}
}
}
//#hint: This is called from main, this function calls binaryPrinter
void print(char c)
{
}
//#hint: this function is only called from print
void binaryPrinter(int value, int *numberOfOnes)
{
}
void print(char c)
{
int n = CHAR_BIT;
binaryPrinter((unsigned char)c, &n);
putchar('\n');
}
void binaryPrinter(int value, int *numberOfOnes)
{
if((*numberOfOnes)--){
binaryPrinter(value >> 1, numberOfOnes);
printf("%d", value & 1);
}
}