Garbage value given as output - c

struct book{
char novel[20];
char author[20];
int pages;
float price;
};
void details(struct book b1){
printf("\nEnter the name of novel,author,no. of pages and price:");
scanf("%s",b1.novel);
scanf("%s",b1.author);
scanf("%d",&b1.pages);
scanf("%f",&b1.price);
}
int main(){
struct book b1;
details(b1);
printf("***NOVEL Details***\n");
printf("\n%s",b1.novel);
printf("\n%s",b1.author);
printf("\n%d",b1.pages);
printf("\n%.2f",b1.price);
return 0;
}
I've tried the same program with a structure of arrays and it works completely fine. Problem arises when a single structure is passed into function and it gives garbage value. I guess there is some problem when calling by value and not address. Please correct me if you find any error

You are correct that the problem is happening due to not passing by reference. Otherwise b1 in main isn't being set and you are just printing whatever values it was initialized with.
Try passing your struct as by reference instead of value for details function
from
void details(struct book b1)
to
void details(struct book * b1)
and changing b1.novel to b1->novel where it is appropriate (in the details() function). You use this syntax for struct pointers. b1->novel is just syntactic sugar for (*b1).novel which is dereferencing the pointer before access the value

Related

C- Passing entire structure variable

Here is a simple C programs in structure but i dont quite get what am i doing wrong as the output is not what i desired ,
P1
#include<stdio.h>
struct book
{
char name[10];
char author[10];
int refno;
};
//passing whole structure variable
void display(struct book b)
{
printf("%s %s %d",b.name,b.author,b.refno);
}
int main()
{
struct book b1={"LET US C","YPK",25};
display(b1);
}
Here this one works completely fine with output:
LET US C YPK 25
--------------------------------
Process exited after 0.3952 seconds with return value 0
Press any key to continue . . .
BUT if i try
struct{
// element -1;
//element -2;
//element-3;
}b1;
/*then*/
int main()
{
b1={"LET US C","YPK",25};
display(b1);
It shows error messages:-
1:[Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11
2:[Error] no match for 'operator=' (operand types are 'book' and '<brace-enclosed initializer list>')
3:[Note] candidate is:
4:[Note] book& book::operator=(const book&)
5:[Note] no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'const book&'
The same messsages are shown if i try :
struct book
{
//elements declarations as p1
}b[10];
int main()
{
b[1]={"LET US C","YPK",25};
display(b[1]);
}
OR WITH
struct book
{
//elements declarations as p1
};
int main()
{
struct book b[10];
b[1]={"LET US C","YPK",25};
display(b[1]);
}
So whats the problem?
and actually my main objective was to define array of structure, as in second last and last
method but it does not seem to work so please help>
In C, the syntax {elem1, elem2, elem3, ...} is only valid if you are initializing a structure (or an array) not assigning one. That's why it doesn't work in your example.
When you write b[1]={"LET US C","YPK",25}; you are trying to assign a value not initializing one.
For short:
Initializing is when you give a value to a variable that you are creating at the moment
Assigning is when you give a value to a variable already created.
For you example to work you can write this
struct book
{
char name[10];
char author[10];
int refno;
};
int main()
{
struct book b[10];
b[1]=(struct book){"LET US C","YPK",25};
^^^^^^^^^^^^
display(b[1]);
}
Now, you can declare structure variable anywhere, either right after structure declaration or anywhere in the main function but the point to be noted is when you are defining/assigning any of the variable i have used
(struct book) on the right hand side of assignment operator which helps compiler to understand that b[1] variable belongs to struct book data type, which corrects the error present in the program.
This feature of C language is known as compound literal.

struct variable cannot access struct members

I was working on a a few basic implementations of structures in C. The goal of my program is to access the members of struct using variables instead of pointers.
This is my program:
#include<stdio.h>
#include<string.h>
struct oldvar{
char name[100];
int age;
float height;
};
void main()
{
struct oldvar DAD;
printf("\nThe old values are %s\n%d\n\f",DAD.name,DAD.age,DAD.height);
strcpy("Will Smith",DAD.name);
DAD.age = 50;
DAD.height = 170;
printf("The updated values are %s\n%d\n\f",DAD.name,DAD.age,DAD.height);
}
On implementing this, I got only the garbage values and no updates :
The old values are ⌡o!uC&uⁿ■a
3985408
How can I update my structure members using variables?
The line
strcpy("Will Smith",DAD.name);
is wrong.
According to strcpy(3) - Linux manual page:
char *strcpy(char *dest, const char *src);
The destination (where to write the copy) is the first argument and the source (what should be copied) is the second argument.
Therefore, the line should be
strcpy(DAD.name,"Will Smith");
Also using values of uninitialized non-static local variable invokes undefined behavior, allowing anything to happen.
For more safety, you should initialize the variable DAD before printing. In other words, the line
struct oldvar DAD;
should be (for example)
struct oldvar DAD = {""};
As mentioned in other answers, the first argument to strcpy() is the destination. Plus there were errors in printf too. It was supposed to be %f, not \f
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
struct oldvar {
char name[100];
int age;
float height;
};
int main(void)
{
struct oldvar DAD={"\n",0,0.0};
strcpy(DAD.name,"will Smith");
printf("\nThe old values are %s\n%d\n%f", DAD.name, DAD.age, DAD.height);
DAD.age = 50;
DAD.height = 170;
printf("The updated values are %s\n%d\n%f", DAD.name, DAD.age, DAD.height);
}
strcpy("Will Smith",DAD.name); --> strcpy(DAD.name, "Will Smith");
strcpy("Will Smith",DAD.name); will copy DAD.name to some constant memory that contain "Will Smith" (Read only memory part).
So that, your program will crash because there is an attempt to write on READ Only Memory part

Pointers + structs + functions in C identifier undefined

So this is my code and I don't understand why I get that identifier "pers" is undefined, when I'm clearly pointing at it from another function, which is as far as I know, the utility of pointers.
I've gone through some research but nothing seemed to solve my issue since I'm dealing with structs and all that.
Also one of the requirements is that tle so called "leer_persona();" cant have any value in the parenthesis
#include <stdio.h>
typedef struct{
int num;
char letra;
}tdni;
typedef struct{
char nom[20];
tdni dni;
}tpersona;
tpersona leer_persona();
void mostrar_persona(tpersona p);
int main(){
tpersona pers;
pers = leer_persona();
mostrar_persona(pers);
return 0;
}
tpersona leer_persona(){
int i=0;
int *fp;
fp = &pers;
Thanks.
Pers has function scope in "main()". It is not visible outside of "main()".
https://www.geeksforgeeks.org/scope-rules-in-c/
Function scope begins at the opening of the function and ends with the
closing of it.
See this link for more details: C - Scope Rules
If you want to use "pers" in another function, you'd typically pass it as a function parameter, e.g. tpersona leer_persona(tpersona * pers). In this example, I passed parameter "pers" by reference, instead of copying by value.

C: Putting a function pointer in a structure where the function uses that structure as an argument

I seem to have run into a chicken and egg problem.
I want to have a structure that as one of its members is a function pointer. However this function pointer wants to use that same structure as it's argument. This creates an issue where I have to define the function pointer before I can include it as a member, but I can't properly define it until I've defined the structure.
I have found that if I simply leave the argument list for the function pointer blank it SEEMS to work, though what I have read is that this is potentially fraught with issues.
Below is what I currently have:
#include <stdio.h>
typedef void (*IO_fun_ptr_t)();
typedef struct IO_config_t{
int address;
IO_fun_ptr_t IO_fun_ptr; //pointer to the function to be used
} IO_config_t;
void print_address (IO_config_t *input){
printf("The address is %d \n", input->address);
printf("Push any key to continue:");
getchar();
}
void main()
{
IO_config_t input = {.address = 16,
.IO_fun_ptr = &print_address};
input.IO_fun_ptr(&input);
}
The result is:
The address is 16
Push any key to continue:
This works but I'm concerned about the potential implications of leaving that argument blank.
As a bit of an aside, I originally thought that I should be able to use void* as an argument as a placeholder for pointer to an unknown argument type, but I would get compile errors when doing so at the point where I assign the pointer to my function:
typedef void (*IO_fun_ptr_t)(void *);
(Error[Pe144]: a value of type "void (*)(IO_config_t *)" cannot be
used to initialize an entity of type "IO_fun_ptr_t")
Any advice on how to do this better and cleaner?
Use forward-declarations.
This is a way of stating that a structure exists, but without providing details of all the members of the structure until later.
#include <stdio.h>
// 1.) Forward declaration: Here is the name of the structure
// but member-details are omitted.
struct IO_config_t;
// 2.) typedef of the structure
// Still no details on the members.
typedef struct IO_config_t IO_config_t;
// 3.) The parameter to the function is listed, using the definition
// from step 2.) (note: Still no details on the members yet)
typedef void (*IO_fun_ptr_t)(IO_config_t* input);
// 4.) Now we actually detail the members of the structure
struct IO_config_t{
int address;
IO_fun_ptr_t IO_fun_ptr;
};
void print_address (IO_config_t *input){
printf("The address is %d \n", input->address);
printf("Push any key to continue:");
getchar();
}
void main()
{
IO_config_t input = {.address = 16,
.IO_fun_ptr = &print_address};
input.IO_fun_ptr(&input);
}
This is demonstrated in the short program: https://ideone.com/p3jBYt
So I had searched through stack exchange and couldn't find anything so humbled myself to asking a question. Just as I'm getting to the end of writing everything up, I glance over to the "Similar Questions" box to the right, and I happen to see the following question that I didn't come across before:
How to properly define a function pointer in struct, which takes struct as a pointer?
And in its answer I found my answer. I simply have to define the function pointer in the structure itself, not before hand. (I had tried, but forgot to include the struct keyword in the definition so it didn't work since the type def wasn't complete I am guessing).
Below is what compiles clean and seems to work:
#include <stdio.h>
typedef struct IO_config_t{
int address;
void (*IO_fun_ptr)(struct IO_config_t *); //pointer to the function to be used
} IO_config_t;
void print_address (IO_config_t *input){
printf("The address is %d \n", input->address);
printf("Push any key to continue:");
getchar();
}
void main()
{
IO_config_t input = {.address = 16,
.IO_fun_ptr = &print_address};
input.IO_fun_ptr(&input);
}

Questions about a college project

I have
the struct:
typedef struct Rental {
int nDays;
float kmsDriven;
char carLicensePlate[LICENSE_PLATE_LENGTH+1];
char *clientName;
char chargingCategory;
} Rental;
Different -Rental type- structs are stored and accessed via a dynamically allocated array of pointers (here is a part of the project):
int main (){
Rental *rentals;
int max_num;
printf("Give a number of rentals you would like to store and manage: ");
scanf("%d", &max_num);
rentals=(Rentals *)malloc(max_num * (sizeof(Rental)))
This is what I have thought of so far but I can't understand it completely...so:
I'm having trouble understanding how *rentals can be an array. I mean shouldn't I declare it at least this way: Rental *rentals[];? I know that if I compile the above code I will see an error...but why?
I've read numerous posts here in Stack Overflow about doing this with double pointers (Rental **rentals;) but the code other people have posted is often very hard for me to read (I don't know all the functions etc. etc.)
Let's say I have the object rentals[0] which will be a pointer towards rentals. If I wanted to pass the struct to a function, should I write:
variable=function(*arguments*... , Rental *rentals[0]);?
rentals is a pointer, not an array, but it is a pointer to the first (zeroth) element of a block of max_num structures, so it can be treated as an array in that you can use rentals[n] to refer to the nth element of the array.
This is not a question and hence it is unanswerable.
Let's say I have the object rentals[0] which will be a pointer towards rentals. If I wanted to pass the struct to a function, should I write: variable=function(*arguments*... , Rental *rentals[0]);?
rentals[0] is not a pointer; it is a struct Rental or Rental.
If you want to pass the structure to the function, you write:
variable = function(…args…, rentals[0]);
If you want to pass a pointer to the structure to the function, you write:
variable = function(…args…, &rentals[0]);
or:
variable = function(…args…, rentals);
These pass the same address to the function.
You should be error checking the call to scanf() to make sure you got a number, and you should error check the number you got (it should be strictly positive, not zero or negative), and you should error check the value returned by malloc().
When you declare an array (for example char buffer[10]; the variable is actually pointing to that array. Pointers and arrays are very close together. In fact when you have a pointer where you store an array of data (just like your case with malloc) you can do something like pointer[0] and pointer[1] to get the correct element.
With a pointer in order to access an element you'd normally use *(pointer +1) to get the element on position 1, this is exactly the same as pointer[1].
When you want to pass a struct in an array, you can either give it by value like this:
void function(struct mystruct var)
{
//...
}
int main()
{
struct mystruct var;
function(var);
}
Or by reference (passing the address instead of the data - this is ideal if your structs are big in size) :
void function(struct mystruct *var)
{
//...
}
int main()
{
struct mystruct var;
function(&var);
}
By using an array, you can do it like this (still by reference):
void function(struct mystruct *var)
{
//...
}
int main()
{
struct mystruct var[10];
function(&var[0]);
}
And using a pointer (to an array) :
void function(struct mystruct *var)
{
//...
}
int main()
{
struct mystruct *var;
var = malloc( sizeof(struct mystruct) *10 );
//This will pass the address of the whole array (from position 0)
function(&var);
//This will pass the address of the selected element
function(&var[0]);
}
As you can see, declaring an array or a pointer is almost the same, expect that you have to initialize the pointer-array yourself (with malloc) and as with anything created with malloc you have to free it yourself too.

Resources