This is a c program to reverse the order of words in a sentence(using stacks) read as input, but all I can get is the reverse of the each word in the sentence. How can I reverse the sentence(separated with ' ' or ',')?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// A structure to represent a stack
struct Stack
{
int top;
unsigned capacity;
char* array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (char*) malloc(stack->capacity * sizeof(char));
return stack;
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// Function to add an item to stack. It increases top by 1
void push(struct Stack* stack, char item)
{
if (isFull(stack))
return;
stack->array[++stack->top] = item;
}
char pop(struct Stack* stack)
{
if (isEmpty(stack))
return 0;
return stack->array[stack->top--];
}
// A stack based function to reverese a string
void reverse(char str[])
{
int n = strlen(str);
struct Stack* stack = createStack(n);
// Push all characters of string to stack
int i;
for (i = 0; i < n; i++)
push(stack, str[i]);
for (i = 0; i < n; i++)
str[i] = pop(stack);
}
int main()
{
char str[50];
fgets(str, sizeof(str), stdin);
str[strlen(str)-1]='\0';
reverse(str);
printf("Reversed string is %s", str);
return 0;
}
Try this code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// A structure to represent a stack
struct Stack
{
int top;
unsigned capacity;
//char* array;
char** array;
};
struct Stack* createStack(unsigned capacity)
{
if( capacity < 1 )
{
capacity = 1;
}
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (char**) malloc(stack->capacity * sizeof(char*));
return stack;
}
void resizeStack( struct Stack* stack , int new_size )
{
if( NULL != stack && new_size > stack->capacity ) // Only support expansion
{
char ** old_array = stack->array ;
stack->array = (char**) malloc(new_size * sizeof(char*));
memcpy(stack->array,old_array,stack->capacity * sizeof(char*));
free(old_array);
stack->capacity = new_size ;
}
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack is empty when top is equal to -1
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// Function to add an item to stack. It increases top by 1
void push(struct Stack* stack, char *item)
{
if ( isFull(stack) )
{
resizeStack(stack, stack->capacity * 2 );
}
stack->array[++stack->top] =(char *) malloc(sizeof(char)*(strlen(item) +1));
strcpy(stack->array[stack->top] , item);
}
char * pop(struct Stack* stack)
{
char * ret = NULL;
if(! isEmpty(stack) )
{
ret = stack->array[stack->top];
stack->array[stack->top] = NULL ;
stack->top --;
}
return ret;
}
void freeStack(struct Stack* stack)
{
if( NULL != stack && NULL != stack->array )
{
while( ! isEmpty(stack) )
{
free(pop(stack));
}
free(stack->array);
}
else
{
printf(" freeStack try to free NULL ");
}
}
#define SEPARATER ' '
// A stack based function to reverese a string
void reverse(char str[])
{
int n = strlen(str);
struct Stack* stack = createStack(4);
char sep[2];
sep[0] = SEPARATER;
sep[1] = 0 ;
char * pch = strtok(str,sep);
while( NULL != pch )
{
push(stack,pch);
pch = strtok(NULL,sep);
}
char * swap_buff = (char*)malloc((n+1) * sizeof(char));
char * cp_buff = swap_buff;
do
{
char * top = pop(stack);
strcpy(cp_buff , top);
cp_buff += strlen(top);
*cp_buff++ = SEPARATER;
}while( ! isEmpty(stack) );
swap_buff[n] = 0;
strcpy(str,swap_buff);
freeStack(stack);
}
int main()
{
char str[50];
fgets(str, sizeof(str), stdin);
str[strlen(str)-1]='\0';
reverse(str);
printf("Reversed string is %s\n", str);
return 0;
}
Related
I have faced with a programming challenge, which I had to calculate the sum of every array which is in my nested array.
In this problem the input is given by the user, and we must start from the must inner array, and then sum it with result of outer arrays.
Sample 1:
{1, 2, {3, {4, 5, {6}}, 7}, 8}
Output 1:
6
15
25
36
Sample 2:
{{12, 23, {4, 0, {1}, {1}}}, 0, {1}}
Output 2:
1
1
6
41
1
42
Sample 3:
{1, {2, {{6}}}, {{{7}}}}
Output 3:
6
6
8
7
7
7
16
My idea was to use the Dynamic Prpgramming strategy for solving this problem, but I am not sure about it, and since the limitations in C are a bit more than the other programming languages, everything gets a bit harder.
Edit
I find a similarity between this question, and implementing a calculator using a Stack data structure.
So I decided to implement a stack of strings, and then add all the { and } characters and also numbers to it. I would ignore the spaces and ,. But when reaching a }, we should calculate the sum.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
/*
https://www.techiedelight.com/stack-implementation/
https://stackoverflow.com/a/1922239/20285050
https://stackoverflow.com/a/1726321/20285050
https://stackoverflow.com/a/8257754/20285050 for converting int to string
https://www.educative.io/answers/how-to-convert-a-string-to-an-integer-in-c
https://stackoverflow.com/a/5099675/20285050
*/
struct stack_entry
{
char *data;
struct stack_entry *next;
};
struct stack_t
{
struct stack_entry *head;
size_t stackSize;
};
struct stack_t *newStack(void)
{
struct stack_t *stack = (struct stack_t*)malloc(sizeof *stack);
if (stack)
{
stack->head = NULL;
stack->stackSize = 0;
}
return stack;
}
char *copyString(char *str)
{
char *tmp = (char*)malloc(strlen(str) + 1);
if (tmp)
strcpy(tmp, str);
return tmp;
}
void push(struct stack_t *theStack, char *value)
{
struct stack_entry *entry = (struct stack_entry*)malloc(sizeof *entry);
if (entry)
{
entry->data = copyString(value);
entry->next = theStack->head;
theStack->head = entry;
theStack->stackSize++;
}
else
{
}
}
int isEmpty(struct stack_t *theStack)
{
if (theStack -> stackSize == 0)
{
return 1;
}
return 0;
}
char *top(struct stack_t *theStack)
{
if (theStack && theStack->head)
return theStack->head->data;
else
return NULL;
}
void pop(struct stack_t *theStack)
{
if (theStack->head != NULL)
{
struct stack_entry *tmp = theStack->head;
theStack->head = theStack->head->next;
free(tmp->data);
free(tmp);
theStack->stackSize--;
}
}
void clear(struct stack_t *theStack)
{
while (theStack->head != NULL)
pop(theStack);
}
void destroyStack(struct stack_t **theStack)
{
clear(*theStack);
free(*theStack);
*theStack = NULL;
}
void evaluate(char expression[], int values[])
{
struct stack_t *operations = newStack();
for (int i = 0; i < 1000; i++)
{
char *expChar;
if (expression[i] == ' ' || expression[i] == ',')
{
continue;
}
else if (expression[i] == '{')
{
expChar = &expression[i];
push(operations, expChar);
}
else if (isdigit(expression[i]))
{
char svalue[5];
int value = 0;
while (i < 1000 && isdigit(expression[i]))
{
value = (value * 10) + (expression[i] - '0');
i++;
}
itoa(value, svalue, 10);
push(operations, svalue);
i--;
}
else if (expression[i] == '}')
{
char sans[5];
int ans = 0;
char openBrace = '{';
expChar = &openBrace;
while (!isEmpty(operations) && top(operations) != expChar)
{
char svalue[5];
strcpy(svalue, top(operations));
pop(operations);
int value = atoi(svalue);
ans += value;
values[i] = ans;
// char op[1];
// strcpy(op, top(operations));
// pop(operations);
}
itoa(ans, sans, 10);
push(operations, sans);
}
else {
}
}
}
int main()
{
printf(" ****** please enter an expression for
evaluating******\n");
char data[1000];
fgets(data, 1000, stdin);
int values[1000] = {0};
evaluate(data, values);
}
I will be grateful for any help and advice.
Basically I made a create_app() function to allocate 2 nodes in the stack, each having a pointer to an array[max]; undo() pops the last element, and before returning it, it adds it into the REDO node's array. redo() does the opposite, pops the last element in it's array, putting it into Undo's array before returning it. What did I do wrong ?
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node *node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack != NULL){printf("Out of space!");}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return(S->tos==-1);
}
int
isFull(STACK S)
{
return(S->tos>=S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[++S->tos] = x;
}
}
int
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[++S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
int
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Some small errors were in your code, like these ones in create_app() which seem like typos.
UNDO->arr_stack == (int *) malloc(max * sizeof(int));
REDO->arr_stack == (int *) malloc(max * sizeof(int));
^
|
if(UNDO->arr_stack != NULL){printf("Out of space!");}
^
|
...
and some int returning functions did not return anything in the else part which gave some warnings.
Here is the modified code, which worked fine for me
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define EMPTY_TOS (-1)
typedef struct node* node_ptr;
struct node
{
int arr_size;
int tos;
int *arr_stack;
node_ptr next;
};
typedef node_ptr STACK;
STACK
create_app(int max)
{
STACK UNDO = (STACK) malloc(sizeof(struct node));
STACK REDO = (STACK) malloc(sizeof(struct node));
{
UNDO->arr_stack = (int *) malloc(max * sizeof(int));
REDO->arr_stack = (int *) malloc(max * sizeof(int));
if(UNDO->arr_stack == NULL){printf("Out of space!");
return NULL;}
else
{
UNDO->tos = EMPTY_TOS;
REDO->tos = EMPTY_TOS;
UNDO->arr_size = max;
REDO->arr_size = max;
UNDO->next = REDO;
REDO->next = UNDO;
return UNDO;
}
}
}
int
isEmpty(STACK S)
{
return (S->tos == -1);
}
int
isFull(STACK S)
{
return (S->tos >= S->arr_size-1);
}
void
push(int x, STACK S)
{
if(isFull(S)){printf("Stack full!");}
else
{
S->arr_stack[++S->tos] = x;
}
}
void
undo(STACK S)
{
if(isEmpty(S)){printf("Nothing to undo!");}
else
{
S->next->arr_stack[++S->next->tos] = S->arr_stack[S->tos];
printf("%d",S->arr_stack[S->tos--]);
}
}
void
redo(STACK S)
{
if(isEmpty(S->next)){printf("Nothing to redo!");}
else
{
int temp = S->next->arr_stack[S->next->tos];
push(S->next->arr_stack[S->next->tos], S);
S->next->tos--;
printf("%d",temp);
}
}
int main()
{
STACK app = create_app(5);
push(1,app);
push(2,app);
push(3,app);
undo(app);
undo(app);
redo(app);
redo(app);
/* Expected output: 3223 */
return 0;
}
Result:
3223
However, always take precaution in deallocating the memory malloced using free().
My code is basically functions used for making/using a stack. I've tried almost everything, but I don't know why my program is displaying this error:
Error: Syntax error before 'struct'
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#define CAPACITY 128
struct stack_struct {
ElemType items[CAPACITY];
int top;
};
StackPtr stk_create(){
StackPtr s = malloc(sizeof(struct stack_struct));
s->top = -1; // stack initially empty
return s;
}
// TODO
StackPtr stk_clone(StackPtr s) {
return NULL; // temporary placeholder
}
void stk_free(StackPtr s) {
free(s);
}
int stk_push(StackPtr s, ElemType val){
if(s->top == CAPACITY - 1)
struct stack_struct * temp;
temp = (struct stack_struct*)malloc(sizeof(struct stack_struct));
s->top++;
s->items[s->top] = val;
return 1;
}
ElemType stk_pop(StackPtr s){
if(s->top == -1)
abort(); // library function which terminates program!!!
s->top--;
return s->items[s->top+1];
}
int stk_is_full(StackPtr s){
return s->top == CAPACITY-1;
}
int stk_is_empty(StackPtr s){
return s->top == -1;
}
int stk_size(StackPtr s) {
return s->top+1;
}
void stk_clear(StackPtr s){
s->top = -1;
}
void stk_print(StackPtr s) {
int i;
printf("\n----TOP-----\n");
for(i=s->top; i>=0; i--) {
printf(FORMAT_STRING, s->items[i]);
}
printf("---BOTTOM---\n");
}
int main() {
StackPtr sptr;
sptr = stk_create();
stk_push(sptr, 1.7);
stk_push(sptr, 3.14);
stk_print(sptr);
stk_pop(sptr);
stk_print(sptr);
stk_free(sptr);
}
As I could see, function stack_push should look like this
int stk_push(StackPtr s, ElemType val){
if(stk_is_full(s))
return -1; // stack already full, we couldn't push new elem
s->top++;
s->items[s->top] = val;
return 1;
}
I think error in this line (line 35 in your source code):
struct stack_struct * temp;
. Let's try
typedef struct stack_struct * temp;
or change declare struct
struct stack_struct {
ElemType items[CAPACITY];
int top;} stack;
and then call
stack* temp;
in line 35.
This question already exists:
C- How can I push Strings to stack one element at a time?
Closed 7 years ago.
Currently my code uses a stack and pushes a user entered string into the stack one by one. However I would like to make it dynamic, what would I malloc/realloc, I know I'm missing something completely obvious but I guess I have tunnel vision... help?
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 100
char a [MAXSIZE];
char * p = a;
int top = -1;
void push ( char n )
{
if ( top == 99)
{
printf( "stack overflow");
return;
}
top+=1;
a[top] = n;
}
/* Function to delete an element from the stack */
void pop(){
if(top == -1)
printf("Stack is Empty");
else
top-=1;
}
char *inputString(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
char *str;
int ch;
size_t len = 0;
str = realloc(NULL, sizeof(char)*size);//size is start size
if(!str)return str;
while(EOF!=(ch=fgetc(fp)) && ch != '\n'){
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(char)*len);
}
int balanced (char * m){
int size = sizeof(m);
int i, j;
for (i=0; i<=size; ++i){
push(m[i]);
}
}
int main(void){
char *m;
printf("input string : ");
m = inputString(stdin, 10);
printf("%s\n", m);
balanced(m);
int i;
for (i=0;i<=sizeof(a);++i){
printf("\n%c", a[i]);
}
free(m);
return 0;
}
If I understand your question properly, this is what you are supposed to do.
struct Stack
{
char c;
struct Stack *next;
}*stack = NULL;
char pop()
{
if(stack == NULL)
{
printf("Stack Underflow\n");
return NULL;
}
c = stack -> c;
struct Stack * temp = stack;
stack = stack -> next;
free(temp);
return c;
}
void push(char c)
{
struct Stack * temp = malloc(sizeof(struct Stack));
temp -> next = NULL;
temp -> c = c;
if (stack == NULL)
stack = temp;
else
{
temp -> next = stack;
stack = temp;
}
}
So all I'm trying to do is free a pointer and it just gives me the error 'invalid address'; though the address is clearly valid, as illustrated by the prints I put in. It tries to free the address of the pointer, but still fails. Through valgrind, it gives the error invalid free() saying the address is on thread 1's stack? The code below is runnable; can anyone help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define SUCC 1
#define FAIL -1
typedef struct bucket {
char *key;
void *value;
struct bucket *next;
} Bucket;
typedef struct {
int key_count;
int table_size;
void (*free_value)(void *);
Bucket **buckets;
} Table;
extern unsigned int hash_code(const char *key) {
unsigned int hash = 0, i = 0;
while(i < strlen(key)) {
hash ^= ((hash << 3) | (hash >> 29)) + key[i++];
}
return hash;
}
/*Makes copy of string and returns pointer to it*/
char * cpy(const char *str) {
char *new = malloc(sizeof(char *));
if(new)
strcpy(new, str);
return new;
}
int create_table(Table ** table, int table_size, void (*free_value)(void *)) {
*table = malloc(sizeof(Table));
if(table && table_size != 0) {
int i = 0;
(*table)->key_count = 0;
(*table)->table_size = table_size;
(*table)->free_value = free_value;
(*table)->buckets = calloc(table_size, sizeof(Bucket *));
while(i < table_size)
(*table)->buckets[i++] = NULL;
return SUCC;
}
return FAIL;
}
int put(Table * table, const char *key, void *value) {
if(table && key) {
int hash = hash_code(key)%table->table_size;
Bucket *curr = table->buckets[hash];
while(curr) {
if(strcmp(curr->key, key) == 0) {
if(table->free_value)
table->free_value(curr->value);
printf("addr of ptr: %p\n", value);
curr->value = value;
printf("addr of curr ptr: %p\n", curr->value);
return SUCC;
}
curr = curr->next;
}
curr = malloc(sizeof(Bucket));
curr->key = cpy(key);
printf("addr of ptr: %p\n", value);
curr->value = value;
printf("addr of curr ptr: %p\n", curr->value);
curr->next = table->buckets[hash];
table->buckets[hash] = curr;
table->key_count++;
return SUCC;
}
return FAIL;
}
int remove_entry(Table * table, const char *key) {
if(table && key) {
int hash = hash_code(key)%(table->table_size);
Bucket *curr = table->buckets[hash], *prev = table->buckets[hash];
while(curr) {
printf("attempt");
if(strcmp(curr->key, key) == 0) {
void * test = curr->value;
printf("at addr %p\n", test);
table->free_value(test);
printf("freed");
if(table->free_value){
table->free_value(curr->value);
}
free(curr->key);
curr->key = NULL;
curr->value = NULL;
table->key_count--;
if(prev == curr)
table->buckets[hash] = curr->next;
else
prev->next = curr->next;
free(curr);
curr = NULL;
return SUCC;
}
prev = curr;
curr = curr->next;
}
}
return FAIL;
}
And the test file that shows the error:
#include <stdio.h>
#include <stdlib.h>
#include "htable.h"
int main() {
Table *t;
int num2 = 3;
printf("create: %d\n",create_table(&t, 2, free));
printf("addr of ptr: %p\n",(void *)&num2);
printf("put %s: %d\n","test",put(t, "test", &num2));
printf("rem key: %d\n",remove_entry(t, "test"));
return 0;
}
This is broken:
char *new = malloc(sizeof(char *));
The amount of memory you need is based on what you need to store, which is the string. You want:
char *new = malloc(strlen(str) + 1);
Or, better yet, just use strdup.
You are trying to free() a stack variable: num2 (in main()):
int num2 = 3;
Later, you have this call:
printf("put %s: %d\n","test",put(t, "test", &num2));
You're passing the address of num2 to put(), which means that remove_entry() will try to free it later. This is illegal. You cannot free a variable allocated on the stack. You should dynamically allocate num2 instead:
int* num2 = malloc(sizeof(int));
*num2 = 3;
There's another problem as well though. In this code:
void * test = curr->value;
printf("at addr %p\n", test);
table->free_value(test);
printf("freed");
if(table->free_value){
table->free_value(curr->value);
}
You are freeing curr->value twice, because you're freeing test which is just a copy of the pointer.