How to push scanned values to a stack in C? - c

I guess there is a problem in scanning the values from keyboard to the stack array using scanf. I'm not sure how to enter scanned values to the array in the stack. Please correct my C code. Check my main method where I ask for user inputs and try to push them to the array.
#include<stdio.h>
#define STACKSIZE 5
struct stack
{
float data[STACKSIZE];
int sp;
};
struct stack sta={{0},-1};
//push method
void push(float n)
{
sta.data[++sta.sp]==n;
//onlystack.data[++onlystack.sp]=x;
}
//pop method
float pop()
{
return sta.data[sta.sp--];
}
//top method
float top()
{
return sta.data[sta.sp];
}
//full method
int full()
{
return (sta.sp==STACKSIZE-1);
}
//empty method
int empty()
{
return (sta.sp==-1);
}
int main()
{
int x, y;
int temp;
for (x=0; x<STACKSIZE; x++)
{
**printf("Enter float to be stored in the stack");
scanf("%f", &temp);
push(temp);**
}
while(!empty(sta))
{
for (y=0; y<STACKSIZE; y++)
{
printf("\t%f",pop());
}
}
printf("%f", top());
return 0;
}

Thoughts:
In push(), you test for equality instead of performing assignment.
temp is of type int. It should be a float.
empty() takes no arguments, and you pass it one.
The last printf("%f", top()) will invoke undefined behavior, because you will print sta.data[-1].
You don't really need the while loop and the for loop around the pop() printing. You should be able to just do the while loop.
To make your output more readable, you should probably print '\n' characters after each float, which will make each float be seen on their own line.
Once these errors are fixed, the code appears to work correctly:
code: https://gist.github.com/sharth/3f67f2790e6a337ada47
runtime: https://gist.github.com/sharth/fdd7af6d6630b335df09

A major problem here is that you give the format "%f" (for floating point) to scanf, but you give it a pointer to an int. This will cause the value to be something completely unexpected.
Also, in the loop where you print the values, why have a nested loop? The outer loop is all that's needed.

Related

Using function to pass the user input via pointers not working

I'm trying to get the input from the user input, and pass to the program main using pointer. It seems that the value isn't going through even tho I tried some alternatives.
For example, if i input 0.0001, when I return to the main function it outputs 0.0000
#include <stdio.h>
void inputFloat(float *n);
int main() {
float *number;
printf("Insert number: ");
inputFloat(number);
printf("%1.4f", *number);
return 0;
}
void inputFloat(float *n){
float num;
while (scanf("%f", &num) != 1 || num < 0) {
scanf("%*[^\n]%*c");
printf("insert positive: ");
}
printf("%1.4f\n", num);
n = &num;
}
Thanks in advance for any tip or correction.
The main problem here is that you forget that in C arguments are passed by value, and that includes pointers.
The argument variable n in the inputFloat function is local to the inputFloat function, all modifications (like assignments) to it will be lost once the function returns.
What I believe you are trying to to is emulating pass by reference, which indeed is done by using pointers. But then you pass a pointer to a normal variable using the address-of operator &:
float number; // Not a pointer
inputFloat(&number); // Pass a pointer to the variable number
To use this pointer, and to set the value of the original variable it points to, you need to dereference the pointer:
void inputFloat(float *n)
{
// ...
*n = num; // Copy the value of num to the location where n is pointing
}

How to get a int with scanf()

void pedir_diag(int* diag){
scanf("%i", &diag);
}
int main() {
int number;
pedir_diag(&number);
return 0;
}
When I compile introduce an integer and expect that number int variable in the main have the value introduced but is not set
I have this, in my code but i am not able to set diag variable with scanf() function.
diag is already a pointer so no need for the address-of operator (&) in the call to scanf():
void pedir_diag(int *diag)
{
scanf("%d", diag);
}
But to do it that way is kinda stupid. You have no way to check for erroneous input.
Better:
#include <stdbool.h>
bool pedir_diag(int *diag)
{
return scanf("%d", diag) == 1; // *)
}
*) scanf() returns the number of successful conversions, so if the number of successful conversions is 1 we return true.
Usage:
#include <stdio.h>
int main(void)
{
int foo;
if (!pedir_diag(&foo)) {
fputs("Input error :(\n\n", stderr);
}
else {
// have fun with foo
}
}
The best way to use scanf through your entire coding life is by remembering the following rule
scanf("%[direction_of_what_to_scan][special format character]",
Pointer_on_some_memory_location);
What scanf does is that it stores what the input was (with some length restrictions) to a memory address. So, either:
int n1;
scanf("%d",&n); //which means the address of variable n1 in memory
or
int *n2 = &n1;
scanf("%d",n) // &doesn't need to be used cause n2 is now already pointer to an integer
Both will are different implementations of the same thing, they differ to the part of using pointers,for which C is well-known,and even applicable these days.

Finding the maximum of an array recursively

I am learning recursion. As an exercise I am trying to find the maximum of an array recursively.
int recursive (int *arr, int n, int largest) {
if(n==0)
return largest;
else {
if (*(arr+n)>largest) {
largest = *(arr+n);
recursive(arr, n-1, largest);
}
}
}
int main() {
int length = n-1;
int largest = v[0];
int z = recursive(arr, length, largest);
printf("\n%d", z);
}
I followed your suggestions, using pointers instead of arrays, and probably the program looks way better. But still it is not doing it's not showing the maximum correctly. I think the logic is correct.
First thing pay attention to compiler warnings, your recursive function doesn't return value when you enter the else part.
Now the second thing is please don't use things like *(arr+n) which is hard to read instead use arr[n], also while just a preference when using arrays as function arguments use int arr[] to call the function instead of int *arr (in the first version it's clear you should pass an array).
Third thing is to name your things instead of int recursive describe what the function is doing for example int maxElemRecursive
So your recursive function should be something like
int maxElemRecursive(int arr[],int n,int largest)
{
if(n==0) return largest;
if(arr[n] > largest) // No need for else because return largest; would've returned value;
{
largest = arr[n];
}
return maxElemRecursive(arr,n-1,largest); // You have to return the value of the function.
// You still pass the array with just arr.
}
In C usually you can't declare an array whose size is unknown at compile-time, hence int v[n] is dangerous code.
Depending on your compiler and the compiler's settings this could be a compile error or it could be a bug.
For such problems you need to learn about pointers and dynamic memory allocation.
Side-note: After C99 there are stuff like Variable Length Arrays but the rules are a little advanced.
Also to pass an array to a function you give the array a pointer as an argument:
int z = recursion(v, n, v[0]);
instead of:
int z = recursion(v[n], n, v[0]);

Infix to reverse polish notation

I am writing a code to convert infix expression to reverse notation but my program is crashing on executing the file
typedef struct stack
{
char a[400];
int top;
}
stack;
stack s;
void push(char *,int);
int pop();
int main()
{
char x[400];
int len,i,y;
puts("Enter string");
scanf("%s",x);
len=strlen(x);
for(i=0;i<len;i++)
{
//considering user is entering only the small alphabets
if((x[i])>=97&&x[i]<=122)
printf("%s",x[i]);
else
//if encountering the operator then pushing it into stack
if(x[i]=='/'||x[i]=='*'||x[i]=='+'||x[i]=='-')
{
push(x,i);
}
else if(x[i]=='(')
continue;
//When encountering the ')' then popping the operator
else
{
y=pop();
printf("%c",y);
}
}
return 0;
}
Passing array and its size as argument
void push(char *x,int i)
{
stack s;
s.top++;
s.a[s.top]=x[i];
}
Returning the popped operator on finding out the ")"
int pop()
{
stack s;
int temp;
temp=s.a[s.top];
s.top--;
return temp;
}
In your code
printf("%s",x[i]);
is wrong. What you want is
printf("%c",x[i]);
AS per the C11 standard, chapter 7.21.6.1, %s format specifier
If no l length modifier is present, the argument shall be a pointer to the initial
element of an array of character type. ...
but here x[i] is of type char.
Also, from paragraph 9,
If any argument is
not the correct type for the corresponding conversion specification, the behavior is
undefined.
So, your code invokes undefined behaviour.
Next, for both the functions, push() and pop(), you're defining a local variable stack s; which is created on each call to those functions and destroyed upon finishing execution. You may want to use the gloabl variable instead. Remove the local variables, they are not needed.
Also, for both the functions, you're using s.top value as the index of s.a array but without any boundary check on the same. You should put a check on the array index value for stack full case (push()) and stack empty case (pop()) before using s.top value as index. The increment and decrement of the s.top should also be placed under the check.
EDIT:
For the logical part, after parsing all the inputs, you should chcek if there is any element left on the stack to be popped or not. You should print the stack containts untill the stack becomes empty to get the complete notation. Check my comment below for the idea of a pseudocode.
Note: As per C standard, int main() should be int main(void)

Passing pointers to an array as arguments to a function

I am trying to implement INSERTION SORT here in C, which I think I've done successfully. However, I am having problems in passing arrays as arguments.
I want in place sorting, which means that the original array passed into the insertion_sort function should contain the elements in the sorted array itself.
#include<stdio.h>
int * insertion_sort(int *a,int length)
{
int j;
for(j=1;j<length;j++)
{
int i,key=a[j];
for(i=j-1;j>=0;j--)
{
if(a[i]<=key)
break;
a[i+1]=a[i];
}
a[i+1]=key;
}
return *a;
}
int main(void)
{
int a[]={10,12,7,6,9,8};
insertion_sort(a,6);
int i;
for(i=0; i<6; i++)
printf("%d\n", a[i]);
return 0;
}
EDIT
Nothing gets printed in the output screen.
Help me find the bug here. Thanks !!
1.You probably meant to use i in the inner loop:
Change:
for(i=j-1;j>=0;j--)
^^ ^^
to:
for(i=j-1;i>=0;i--)
2.You don't have to return anything as the original array gets modified (which is just as well since you ignore the returned value).
3.Array index starts from 0. Change outer loop to: for(j=0;j<length;j++)

Resources