Function not starting after user input being returned from another function - c

That's the code in C:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char street;
int number;
char postalcode;
} Person;
void print(Person p) {
printf("Street: %s\n", p.street);
printf("Number: %d\n", p.number);
printf("Postal code: %s\n", p.postalcode);
}
Person signUp() {
Person person;
printf("In which street do you live on?: \n");
scanf("%s", &person.street);
printf("What is your number?: \n");
scanf("%d", &person.number);
printf("what is your postal code?: \n");
scanf("%s", &person.postalcode);
return person;
}
int main(void) {
Person person;
person = signUp();
print(person);
return 0;
}
I tried to make the "signUp" function return the user inputs to another function called "print", so it would print the values from the previous function. The "signUp" function works just fine, but the "print" function never starts.

You reading and writing strings with %s but your variables are a single char (which would be the format string %c).
When reading a string with scanf() always use a maximum field width. I am using a str() macro here to not repeat myself. Note: usually we prefer using sizeof() but you need sizeof(p->street)-1 and the order of evaluation of macros gets in the way.
There is nothing wrong with passing in a struct by value and returning them by value, however, this implies copies so we usually pass these in via a pointer instead.
#include <stdio.h>
#include <stdlib.h>
#define POSTALCODE_LEN 5
#define STREET_LEN 20
#define str(s) str2(s)
#define str2(s) #s
typedef struct {
char street[STREET_LEN+1];
int number;
char postalcode[POSTALCODE_LEN+1];
} Person;
void print(const Person *p) {
printf("Street: %s\n", p->street);
printf("Number: %d\n", p->number);
printf("Postal code: %s\n", p->postalcode);
}
void signUp(Person *person) {
printf("In which street do you live on?: \n");
scanf("%" str(STREET_LEN) "s", person->street);
printf("What is your number?: \n");
scanf("%d", &person->number);
printf("what is your postal code?: \n");
scanf("%" str(POSTALCODE_LEN) "s", person->postalcode);
}
int main(void) {
Person person;
signUp(&person);
print(&person);
}
I realize that the typedef saves you from writing struct Person but the downside is that it imports "Person" into the same name space as variable so you cannot do Person Person but have to use a lowercase person. If you need to talk to someone about your code it becomes more tedious "lowercase person" or "uppercase person" to differentiate. Personally (pun), I would use use a short variable name to get around it, i.e. Person p.
I also find snake case easier to read than camel case (sign_up() vs signUp()), and I find the namespace rules easier to remember (constants are upper case, rest is lowercase; with camel case it's methods starts with lower case and then you upper case each words except ... etc).

Related

How to assign fields of a struct from scanning stdin?

I want the program to extract data from the user through the console, by scanning stdin with the scanf() and fgets() and assign the values to named structs, to eventually print them out.
Right the following code is not working. The problem is the code does not recognize the scanned input and the array corona and fails to assign it into that array at index "0".
Here's the code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char name[100];
char phone[100];
} Person;
typedef struct {
char location[100];
char time[100];
} Event;
typedef struct {
Person person;
Event event;
} Corona;
int main() {
/*help variables*/
char* name2;
char* number2;
char* location2;
char* date2;
Corona corona[28]; //creating list with 28 objects just because. it could be 5 or x too.
printf("Name");
fgets(name2, 50, stdin); //user input for name
printf("Nummer/location/date");
scanf("%s %s %s", number2, location2, date2); //user input for phone number, location and date
corona[0]= *(Corona*)malloc(sizeof (Corona)); //allocating memory for array
corona[0]={{("%s",name2),("%s", number2)}, {("%s", location2),("%s", date2)}};
/*printing out the information of array "corona" with index 0"*/
printf("Name: %s\n", corona[0].person.name);
printf("Phone: %s\n", corona[0].person.phone);
printf("Location: %s\n", corona[0].event.location);
printf("Time: %s\n", corona[0].event.time);
return 0;
}
lets fix one part of this and see if you can fix the rest
printf("Nummer/location/date");
scanf("%s %s %s", corona[0].person.phone,
corona[0].event.location,
corona[0].event.time);
no need for any mallocs, fancy casts or whatever that assignment line is tryong to do
ie these lines
corona[0]= *(Corona*)malloc(sizeof (Corona)); //allocating memory for array
corona[0]={{("%s",name2),("%s", number2)}, {("%s", location2),("%s", date2)}};

Output of values of a struct via a function with a pointer as a parameter

I have two structures. A pointer is assigned to one.
Now I would like to output data previously entered via scanf via a function (outputAddress) with a pointer as a parameter.
It works with the variables via the pointer. But how do I do that with the values from the other structure? How can I output this in the function?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct structPerson
{
char name[30];
char forename[50];
int age;
};
struct structAddress
{
int zip;
char location[35];
char street[40];
int hNumber;
struct structPerson *ptrPerson;
};
void outputAddress(struct structPerson *ptrPerson)
{
printf("\n\nOutput Address: \n");
printf("ptrPerson->name: %s", ptrPerson->name);
printf("\nptrPerson->forename: %s", ptrPerson->forename);
return;
}
int main()
{
struct structPerson person1;
struct structAddress address1;
address1.ptrPerson = &person1;
printf("Location: ");
scanf("%s", &address1.location);
printf("Zip: ");
scanf("%d", &address1.zip);
printf("\nName: ");
scanf("%s", &address1.ptrPerson->name);
printf("Forename: ");
scanf("%s", &address1.ptrPerson->forename);
printf("\nOutput: %d %s %s\n", address1.zip, address1.location, address1.ptrPerson->name);
// strcpy( address1.location, "");
// printf("structAddress1: %d %s\n", address1.zip, address1.location);
outputAddress(&person1);
return 0;
}
In your data model structAddress is associated with a person via the personPtr field. As a result, Address is a main data struct. If I understand your intention correctly, you want to print info about the person and then his/her address.
For this you need to do a couple of changes. Firstly, you should pass the Address struct to the print function, because it has all information available, including the pointer to the person. Secondly, you should access your person information using the pointer: ptrAddress->ptrPerson-><field>. Here is an example.
void outputAddress(struct structAddress *ptrAddress)
{
printf("\n\nOutput Address: \n");
// use ptrAddress->ptrPreson to accesss person information
printf("ptrPerson->name: %s", ptrAddress->ptrPerson->name);
printf("\nptrPerson->forename: %s", ptrAddress->ptrPerson->forename);
// use ptrAddress-> to access address fields.
printf("\nptrAddress->zip: %d", ptrAddress->zip);
...
return;
}
int main() {
...
outputAddress(&address1); // << use address1 here.
...
}
Your datamodel is probably broken anyway. The address struct has a pointer to a person, but it often makes more sense to have it the other way around.

Is this a correct usage of struct?

#include <stdio.h>
int main()
{
struct database
{
char name[10];
int number;
int roll;
};
struct database s1,s2;
printf("enter name, number , roll: ");
scanf("%c%d%d",&s1.name,&s1.number,&s1.roll);
scanf("%c%d%d",&s2.name,&s2.number,&s2.roll);
printf("Entered value is :");
printf("%c%d%d",s1.name,s1.number,s1.roll);
printf("%c%d%d",s2.name,s2.number,s2.roll);
}
I've been trying to get output but I don't know if this correct Or should I access them individually? Help would be very much appreciated! thanks :)
If you need the specific struct only within the function body, then your declaration will suffice. But, note that if you want a struct to be used throughout the program, then it needs to be defined like this:
struct database {
...
};
int main(void) {
struct database s1, s2;
...
}
Also, you're trying to accept a single char value:
scanf("%c%d%d", &name, ...);
// --^^--
Here, you are expected to get a char from the user:
scanf("%9s%d%d", name, ...);
Note: The %9s is specifically given to prevent input buffer overflow.
A nicely structured program would look like (notice comments):
#include <stdio.h>
// Don't use magical numbers for constants in the program
// The use macros for this will suffice and look a ton cleaner
#define MAX_LENGTH 64
#define FMT_LENGTH "%63s"
// Our structure
struct database {
char name[MAX_LENGTH];
int number;
int roll;
};
int main(void) {
// You are here only creating single instances of struct
struct database s1, s2;
printf("Enter name, number and roll: ");
// Always check if the values are correctly assigned to their respective
// variables, if not, print error and exit (in this context)
if (scanf(FMT_LENGTH " %d %d", s1.name, &s1.number, &s1.roll) != 3) {
printf("error: One of the values are incorrectly assigned.\n");
return 1; // Exit Failure
}
// Same with s2
printf("Name: %s | Number: %d | Roll: %d\n", s1.name, s1.number, s1.roll);
return 0;
}

Changing a structure from inside of a function

Im suppose to print student details from the user into a student structure and I don't understand why when I compile with linux terminal, there is no entry or output. Please hep me, I'm new here.
This is my code:
#include <stdio.h>
#include <stdlib.h>
struct student
{
char *name;
int id;
char enroll;
};
int main()
{
struct student john;
john.name = "John Smith";
john.id = 12345678;
john.enroll = 'D';
}
void getStudent(struct student *john)
{
printf("Type the name of the student: ");
john->name = malloc(100);
fgets(john->name, 100, stdin);
printf("\nType the student number: ");
scanf("%d", &(john->id));
printf("\nType the student enrollment option (D or X): ");
scanf("%c", &(john->enroll));
return;
}
void printstudent(struct student john)
{
printf("Student name: %s\n", john.name);
printf("Student number: %d\n", john.id);
printf("Student enrollment option: %c\n", john.enroll);
return;
}
You need to call your functions from main (or from any function that needs them). Writing a function (declaring it) doesn't actually execute it.
int main()
{
foo(); // execute foo (call it)
}
void foo()
{
// do stuff
}
Your functions are functions like printf() and scanf() and have to also be called to be used.
You need to invoke the functions you have defined, from the main.
Add this statement inside the main function.
printstudent(john);

Getting multiple struct entries from stdin

I am trying to get multiple entries for my struct via the keyboard. I think I am wrong inside of scanf but I am not sure where I am wrong. Thanks!
Here is what I have:
#include <stdio.h>
#include <math.h>
int main()
{
//define the structure
struct course
{
char title[20];
int num;
} ;
// end structure define
//define the variable
struct course classes;
printf("Enter a course title and course number");
scanf("%s %d", classes[3].title, &classes.num);
return 0;
}
Fix the code as Carl said and it works fine:
#include <stdio.h>
int main()
{
struct course
{
char title[20];
int num;
} ;
struct course class;
printf("Enter a course title and course number");
scanf("%s %d", class.title, &class.num);
printf("%s %d", class.title, class.num);
return 0;
}
There are a couple issues.
You have this struct called "classes", but it has only 1 entry - you're accessing the 3rd entry so you're running off the end.
Also, Title is 20 bytes long, but if you enter something larger in scanf(), it will just overflow. The basic scanf() structure looks ok though.
I would set it up more like this:
#include <stdio.h>
#include <math.h>
#define MAX_CLASSES 50 // how big our array of class structures is
int main()
{
//define the structure
struct course
{
char title[20];
int num;
} ;
// end structure define
//define the variable
struct course classes[MAX_CLASSES];
int nCurClass = 0; // index of the class we're entering
bool bEnterMore = true;
while (bEnterMore == true)
{
printf("Enter a course title and course number");
scanf("%s %d", classes[nCurClass].title, &classes[nCurClass].num);
// if user enters -1 or we fill up the table, quit
if (classes[nCurClass].num == -1 || nCurClass > MAX_CLASSES-1)
bEnterMore = false;
}
}
That's the basic idea. Another improvement that could be made would be checking the length of the course title before assigning it to classes[].title. But you need something to do ;-)

Resources