Using function to pass the user input via pointers not working - c

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
}

Related

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.

how do you increment a variable using a pointer in C? [duplicate]

This question already has an answer here:
Variable changed in function not seen by caller?
(1 answer)
Closed 6 years ago.
My code is about implementing the function of Stack and Queue. If you're wondering why don't I use struct in my program that's because our instructor only allows us to use pointers and I'm a little bit confused using pointers. It's not yet finish, as much as possible I try to finish one function at a time instead of skipping to the next.
#include <stdio.h>
int container[5];
int len=0;
As I understand this part of my in function insert, "len" is suppose to change since it's incremented every time the function is use
int insert(int container[],int len)
{
int i,j,content,*incre;
incre=&len;
for(i=*incre;i<*incre+1;i++)
{
printf("Enter number:\n");
scanf("%d",&content);
container[i]=content;
}
(*incre)++;
}
int printcontent(int container[])
{
int i;
printf("Content of container:\n");
for(i=0;i<len+1;i++)
{
printf("%d ",container[i]);
}
printf("\n");
}
This part asks the user whether to add a content in the container or simply remove it. They can only add or remove one at a time.
int stack(int container[])
{
while(1)
{
int choice;
printf("What do you wanna do?\n");
printf("1.Insert\n2.Pop\n3.isEmpty\n4.Exit\n");
scanf("%d", &choice);
I checked the value of len it remains 0 instead of 1 when I first use insert.
if (choice==1)
{
insert(container,len);
printf("Value of len:%d\n",len);
printcontent(container);
}
else if(choice==4)
{
break;
}
}
}
main()
{
while(1)
{
int choice;
printf("What do you want to do?\n");
printf("1.Stack\n2.Queue\n3.Exit\n");
scanf("%d",&choice);
if(choice==1)
{.
stack(container);
}
else if(choice==3)
{
break;
}
}
}
Thanks for all of your help.
What your insert(...) function does is that it takes the parameter int len by value. That means if you call insert(...) with the local variable len as an argument in main(...) or whereever - it actually copies the value of the local variable len to the argument variable len inside the insert(...) function. The variable len which is inside the insert(...) function is then local to the insert function. That does not change even if you're declaring a pointer named incre pointing to this insert(...)-local variable len.
Then the argument variable len is incremented - but due to the fact that it is a local variable of the insert(...) function you will not see the original local variable len (which is in main(...) e.g.) being changed.
If you want to pass the original len by reference instead of by value, you have to declare your function like this ...
int insert(int container[], int* len) { ... } // Using raw pointers
... or like this ...
int insert(int container[], int& len) { ... } // Using references
... and use it like that (depending on the decision above):
insert(container, &len); // With pointers
insert(container, len); // With references

Pointers in C for a rookie

I am just starting to learn programming for a unit I am doing in my engineering course and I have come across pointers. I just wanted some reassurance that I actually understand the concept correctly in terms of using a pointer as an argument in a function. If I understand it correctly, you pass a pointer to an address of a variable you would like to be altered by a separate function called, even though it is a local variable within the scope of the calling function. Does that make sense? I have an example from my text book which I re-wrote. The only thing is they gave it in two incomplete parts and I put it together, filled in the blanks and added the final printf statement in the main function. I'll paste it here:
#include <stdio.h>
#include <stdlib.h>
#define READ_OK 0
#define READ_ERROR 1
int read_num(int lo, int hi, int *num);
int main(int argc, char *argv[])
{
int lo = 0, hi = 0, *num, val;
printf("Please enter a lower bound and an upper bound for your range,respectively\nLower: ");
scanf("%d", &lo);
printf("Upper: ");
scanf("%d", &hi);
num = &val;
if(read_num(lo,hi, &val) != READ_OK)
{
printf("Read error, program abort\n");
exit(EXIT_FAILURE);
}
else
{
printf("You entered %d, press any key to continue: \n", val);
getchar();
}
return 0;
}
int read_num(int lo, int hi, int *num)
{
int next;
printf("Enter a number between %d and %d: ", lo, hi);
while(scanf("%d", &next)==1)
{
if (lo<=next && next<=hi)
{
*num = next;
return READ_OK;
}
printf("%d is not between %d and %d\nTry again: ", next, lo, hi);
}
return READ_ERROR;
}
So is my understanding correct? "val" gets modified in read_num() by passing it's address in the form of pointer "*num", in which the the value for "next" is then written?
PS: is this syntax correct?
PPS: What would this process specifically be called?
Thanks a bunch for any help :)
The *num is not necessary inside the main() function. As you are passing the address of the val inside the read_num() , so any changes from the read_num() will also affect the value inside main() as you are working with the address.
In your program you have basically use two different pointers- one is inside main which is num, and another inside read_num() which is also num, for more understanding see the scope of a variable in c. As the val is inside main so you don't need to use pointer here, because you have the access of changing the value from the main as it is local to it. You will need pointer when you will be changing the value of val outside from the main, or from outside of the scope of the variable.

Calculate the sum of two numbers using thread

I have this little program I wrote to read two numbers from a user and calculate their sum using a thread function, which is also responsible for displaying the result on the screen.
int global[2];
void *sum_thread(void *arg)
{
int *args_array;
args_array = *(int**)arg;
int n1,n2,sum;
n1=args_array[0];
n2=args_array[1];
sum = n1+n2;
printf("N1 + N2 = %d\n",sum);
return NULL;
}
int main()
{
printf("First number: ");
scanf("%d",&global[0]);
printf("Second number: ");
scanf("%d",&global[1]);
pthread_t tid_sum;
pthread_create(&tid_sum,NULL,sum_thread,(void*)&global);
pthread_join(tid_sum,NULL);
return 0;
}
However, when I run the code, it does not work properly due to a segmentation fault. I suppose I am trying to access/use unallocated memory. Should I allocate it with malloc or is there other things I am doing wrong?
The name of the array, global points to the base address of the array. You can simply pass that and use the same inside your thread function.
However, just to mention a logical point, if you're passing global as a parameter to sum_thread() function, it need not be a global.
In your code, change
pthread_create(&tid_sum,NULL,sum_thread,(void*)&global);
to
pthread_create(&tid_sum,NULL,sum_thread,global);
Then, in sum_thread() function
args_array = *(int**)arg;
to
args_array = arg;
You pass (void*)&global as the thread start function's argument. The type of &global is (*)int[2] -- pointer to array of two int. That is different from and incompatible with int **, which is a pointer to a pointer to int. Arrays are not pointers.
#SouravGhosh already offered a solution that gets the typing correct, and should work just fine. I observe, however, that in this particular case it's a bit silly to pass a pointer to the global array, because the thread could instead just read the array directly:
void *sum_thread(void *arg)
{
int n1,n2,sum;
n1=global[0];
n2=global[1];
sum = n1+n2;
printf("N1 + N2 = %d\n",sum);
return NULL;
}

Declaring arrays in c language without initial size

Write a program to manipulate the temperature details as given below.
- Input the number of days to be calculated. – Main function
- Input temperature in Celsius – input function
- Convert the temperature from Celsius to Fahrenheit.- Separate function
- find the average temperature in Fahrenheit.
how can I make this program without initial size of array ??
#include<stdio.h>
#include<conio.h>
void input(int);
int temp[10];
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
In C arrays and pointers are closely related. In fact, by design an array is just a syntax convention for accessing a pointer to an allocated memory. *(see note for more details below)
So in C the statement
anyarray[n]
is the same as
*(anyarray+n)
Using pointer arithmetic.
You don't really have to worry about the details to make it "work" as it is designed to be somewhat intuitive.
Just create a pointer, and allocate the memory and then access it like as an array.
Here is some examples --
int *temp = null; // this will be our array
// allocate space for 10 items
temp = malloc(sizeof(int)*10);
// reference the first element of temp
temp[0] = 70;
// free the memory when done
free(temp);
Remember -- if you access outside of the allocated area you will have unknown effects.
To be clear it is the indexing operator ([ ]) that is translated to pointer arithmetic. This is not an array in the modern sense of the
type. Whether (or not) the pointer involved points to (dynamically) allocated
memory is inconsequential to how this operator works. In a more modern language you would be able to operate on the array as an abstract type (to see how big it is, for example), you can't do this in C.
An array without an initial size is basically just a pointer. In order to dynamically set the size of the array, you need to use the malloc() or calloc() functions. These will allocate a specified amount of bytes of memory.
In your code above, declare temp as an int pointer
int *temp;
Then allocate space for it using malloc() or calloc(). The argument that these functions take is is the number of bytes of memory to allocate. In this case, you want enough space for d ints. So...
temp = malloc(d * sizeof(int));
malloc returns a pointer to the first byte in the block of memory that was just allocated. Regular arrays are simply pointers to the first byte in a sectioned off block of memory, which is exactly what temp is now. Thus, you can treat the temp pointer as an array! Like so:
temp[1] = 10;
int foo = temp[1];
printf("%d", foo);
Outputs
10
You will need to declare temp as an int pointer (instead of an int array). Then, you can use malloc in your main (after your first scanf):
temp = malloc(d * sizeof(int));
If your compiler supports c99, then simply use VLA(variable length array).Use like this:
void input(int);
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
int temp[d];
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
Now temp[] is defined inside main() after date input.
1-add #include<stdlib.h> at the top of your file. Then modify the conv() code as follows:
2- modify temp declaration as follows (global variable):
int *temp;
3- modify input(int d) function as follows (tested on Visual Studio 2010):
void input(int d)
{
int x=0;
temp=(int*)malloc(sizeof(int)*d);
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
Allocate the "array" dynamically on the heap after you read the size.
I didn't change anything else so you may see it clearly.
#include<stdio.h>
#include<conio.h>
#include <stdlib.h> //here
void input(int);
int *temp=0; //here
int d;
void main()
{
int x=0;
float avg=0,t=0;
printf("\nHow many days : ");
scanf("%d",&d);
temp=malloc(d * sizeof(int)); //here
input(d);
conv();
for(x=0;x<d;x++)
{
t=t+temp[x];
}
avg=t/d;
printf("Avarage is %f",avg);
getch();
}
void input(int d)
{
int x=0;
for(x=0;x<d;x++)
{
printf("Input temperature in Celsius for #%d day",x+1);
scanf("%d",&temp[x]);
}
}
void conv()
{
int x=0;
for(x=0;x<d;x++)
{
temp[x]=1.8*temp[x]+32;
}
}
Maybe it's late to answer but...
If you work with small embedded system you might not have malloc and free functions.
So you have to sacrifice memory for 366 * sizeof(your_type), define it statically and use as a circular buffer. Then you can always slice it by number of days you need to calculate an average value.
Of course this makes natural constrains. You can define it by yourself.

Resources