using strtok in C to assign value to a structure - c

i am receiving a default char array (first/last) in guest_init (and i need to initialize the values such that guest have default values ) is my following code correct? as when i run this g->first_name is always being assigned garbage. need some help.
struct guest {
char last_name[30];
char first_name[30];
};
struct auditorium_seating {
struct guest **seating;
};
void guest_init_default(struct guest *g)
{
*g->first_name = "???";
*g->last_name = "???";
}
void guest_init(struct guest *g, char *info)
{
strcpy(g->first_name, strtok(info, "/"));
strcpy(g->last_name, strtok(NULL, "\0"));
}
void auditorium_seating_init(int rowNum, int columnNum, struct auditorium_seating *a)
{
a->seating=malloc((sizeof(a->seating[rowNum][columnNum])));
char string_arr[30]="aaa/bbb";
for (int i = 0; i<rowNum; i++)
{
for (int j = 0; j<columnNum; j++)
{
//guest_init_default(a->seating);
guest_init(a->seating,string_arr);
}
}
}
auditorium_seating_init being called from main.
void main() {
struct auditorium_seating auditorium_seating;
struct guest temp_guest;
int row, col, rowNum, columnNum;
char guest_info[30];
printf("Please enter a number of rows for an auditorium seating.");
scanf_s("%d", &rowNum);
printf("Please enter a number of columns for an auditorium seating.");
scanf_s("%d", &columnNum);
auditorium_seating_init(rowNum, columnNum, &auditorium_seating);
printf("Please enter a guest information or enter \"Q\" to quit.");
}

Enable your compiler warnings: *g->first_name = "???"; is wrong.
And strtok(NULL, "\0")); is wrong too.
You probably want this:
#include <string.h>
#include <stdio.h>
struct guest {
char last_name[30];
char first_name[30];
};
void guest_init(struct guest *g, char *info)
{
strcpy(g->first_name, strtok(info, "/"));
strcpy(g->last_name, strtok(NULL, "/"));
}
int main()
{
struct guest g;
char info[] = "Foo/Bar";
guest_init(&g, info);
printf("Last Name = %s\n", g.last_name);
printf("First Name = %s\n", g.first_name);
}
There may be more errors related to struct auditorium_seating *a, but you didn't post that code.

No, you must copy data to your structure, as you allocated memory inside it.
Read compiler errors and use it to fix your program.

Related

How can I increment the value in the called function?

How can I pass the pointer to the structure to another function?
sample:
#include<stdio.h>
struct customer{
char name[50];
int number;
};
void input(){
struct customer details;
printf("enter your name: ");
scanf("%s",details.name);
details.number++;
printf("%d\t%s",details.number,details.name);
}
int main(){
struct customer details;
input();
//pcust->number++; how should I declare this?
printf("%d\t%s",details.number,details.name);
}
how do you automatically assign a number in a struct where I can call its value in other functions?
suppose I have this struct
struct customer{
char name[50];
int number;
};
and request input for the user
void input(){
struct customer details;
printf("enter your name");
scanf("%s",details.name);
printf("enter your number");
scanf("%d",&details.number);
}
instead of asking them to enter their number in the function to call it by value, how can I assign it automatically, so I can call it by its value? The possible output I need is like this so that in the next function again, I can call by its value again.
1 customer1
2 customer2
....
#include <stdio.h>
struct customer
{
char name[50];
int number;
};
void input(struct customer *pDetails)
{
printf("enter your name: ");
scanf("%s", pDetails->name);
pDetails->number++;
printf("%d\t%s \n", pDetails->number, pDetails->name);
}
int main()
{
struct customer details = {};
input(&details);
printf("%d\t%s \n", details.number, details.name);
}
Your main problem is that you do not use any function parameters.
You need to have some kind of search (for example if you want to modify a customer record
Use arrays to store multiple data.
Example:
struct customer
{
char name[50];
int somedata;
};
struct database
{
size_t size;
struct customer customers[];
};
struct customer *findCustomer(const struct database *db, const char *name)
{
struct customer *result = NULL;
if(db)
{
for(size_t i = 0; i < db -> size; i++)
if(!strcmp(db -> customers[i].name, name))
{
result = (struct customer *)&db -> customers[i];
break;
}
}
return result;
}
struct database *addCustomer(struct database *db, const char *name)
{
size_t newSize = db ? db -> size + 1 : 1;
db = realloc(db, newSize * sizeof(db -> customers[0]) + sizeof(*db));
if(db)
{
strcpy(db -> customers[db -> size].name, name);
}
return db;
}

Why does printing from this struct give a segmentation fault?

I'm trying to create an array of Product structs and then print the name and code of each Product in the array, but I keep getting a segmentation fault. I have tried to insert each value without a loop and then printing, and it works, but I'd like to automate it. The function fill_products fills the products array according to the user's input, and the select_products prints each name-code pair for the entire array.
This is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int code;
char *name;
float price;
} Product;
void select_products(Product *products, int len)
{
int i;
printf("%-30s%s\n", "Name", "Code");
for (i = 0; i < len; i++)
{
printf("%-30s%d\n", products[i].name, products[i].code);
}
return;
}
void fill_products(Product *products, int len)
{
int i, code;
char *name;
float price;
for (i = 0; i < len; i++)
{
printf("Insert product name (%d / %d): ", i + 1, len);
scanf("%s", &name);
printf("Insert product price (%d / %d): ", i + 1, len);
scanf("%f", &price);
products[i].code = i;
products[i].name = name;
products[i].price = price;
}
return;
}
int is_alloc(Product *products)
{
if (products == NULL)
{
printf("Error: memory allocation unsuccessful.\n");
}
return products != NULL;
}
int main(void)
{
int len, n_bytes;
Product *products;
printf("Insert length of array: ");
scanf("%d", &len);
n_bytes = sizeof *products * len;
products = malloc(n_bytes);
if(!is_alloc(products))
{
exit(0);
}
fill_products(products, len);
select_products(products, len);
free(products);
return 0;
}
I keep getting a segmentation fault.
Please enable compiler warnings, and pay attention to them.
This code:
char *name;
...
scanf("%s", &name);
is bogus and doesn't do at all what you intend.
You must either allocate space for name separately (and then not forget to free() it), or make that space available in the Product structure like so:
typedef struct
{
int code;
char name[100];
float price;
} Product;
(this assumes there is a reasonable limit on name length).

C program - skipping user input

I created a program that uses arrays and array pointers to store a user's animal name, category of animal, and age. But when I run it, there is a segmentation fault after I type the name age and category. I was wondering if someone could guide me in how to fix it, I am very new to C programming.
This is the task I am supposed to complete:
Write a program that defines an animal data type, with an animal name, age, and category (cat, dog, etc.), as well as an animal array type that stores an array of animal pointers.  Your program will prompt the user to enter the data for as many animals as they wish.  It will initialize a dynamically allocated animal structure for each animal, and it will store each animal in an instance of the animal array structure.  Your program will then print all the animal information to the screen.  You will upload your C program as one file.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char *name;
char *category;
int age;
} AnimalType;
typedef struct {
AnimalType basicInfo;
AnimalType *arr[];
} AnimalArrayType;
void initAnimal(char *n, char *c, int a, AnimalArrayType *ar);
void printAnimal(const AnimalArrayType *stuPtr);
int main() {
AnimalArrayType *array;
int numAn;
char name[20];
char category[20];
int age;
printf("Please enter the number of animals you want to input: ");
scanf("%d", &numAn);
array = calloc(numAn, sizeof(AnimalArrayType));
for (int i=0; i<numAn; ++i) {
printf("Enter animal name: ");
scanf("%s", name);
printf("Enter their category: ");
scanf("%s", category);
printf("Enter age: ");
scanf("%d", &age);
initAnimal(name, category, age, array + I);
}
printf("\n LIST:\n");
for (int i=0; i<numAn; ++i) {
printAnimal(array + I);
}
return 0;
}
void initAnimal(char *n, char *c, int a, AnimalArrayType *ar)
{
strcpy(ar->basicInfo.name, n);
strcpy(ar->basicInfo.category, c);
ar->basicInfo.age = a;
}
void printAnimal(const AnimalArrayType *stuPtr)
{
printf("Animal: %s, Category: %s age %d\n",
stuPtr->basicInfo.name, stuPtr->basicInfo.category,
stuPtr->basicInfo.age);
}
The char *name and char *category fields in the AnimalType struct are being initialized to NULL (from the call to calloc()), but you don't allocate any char[] memory for them to point at afterwards, so you end up crashing in initAnimal() when it tries to copy data into those fields using strcpy().
You need to either:
change those fields into char[] arrays instead of char* pointers:
typedef struct {
char name[20];
char category[20];
int age;
} AnimalType;
allocate memory for them to point at, such as from strdup():
typedef struct {
char *name;
char *category;
int age;
} AnimalType;
...
void initAnimal(char *n, char *c, int a, AnimalArrayType *ar)
{
ar->basicInfo.name = strdup(n);
ar->basicInfo.category = strdup(c);
ar->basicInfo.age = a;
}
Don't forget to free() anything you dynamically allocate when you are done using it.

Username and Password in C

so basically I want to create a program that asks for an username and a password in order to enter the actual program. I tried doing something like that but when I type the first username and password it doesn't let me go through. On the other hand when I type the second username and password it does work. Can someone explain me why?
#include<stdio.h>
#include<string.h>
#define MAX 100
#define LEN 40
int names(char listName[][LEN]);
void pass(char listPass[][LEN]);
int main()
{
char name[LEN];
char password[LEN];
char listName[MAX][LEN];
char listPass[MAX][LEN];
int i;
names(listName);
pass(listPass);
printf("Enter username: ");
scanf("%s", name);
printf("Enter password: ");
scanf("%s", password);
for(i = 0; i< 2; i++)
{
if (strcmp(listName[i], name) == 0 && strcmp(listPass[i], password) == 0)
{
printf("Access granted\n");
break;
}
else
{
printf("Access denied\n");
break;
}
}
getch();
}
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
Compile with warnings enabled and you'd see that the variable i is used uninitialized here:
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
What you have now is undefined behaviour, i.e. anything can happen. More likely you'd just get a random crash.
You meant strcpy(listName[0], "Vince");, strcpy(listName[1], "Jeremy");
However, what you'd really want to do is to define these variables *out of main, and initialize them there. Also, allow for varying length passwords and usernames by using an array of pointers to char. For example:
char *listName[MAX] = { "Vince", "Jeremy" };
char *listPass[MAX] = { "aBc2xyz8", "fa7saC12" };
int main(void) { ...
Or even better, use a structure for user data:
struct user_data {
char *username, *password;
};
struct user_data users[MAX] = {
{ "Vince", "aBc2xyz8" },
{ "Jeremy", "fa7saC12" }
};
In names() and pass() you use i uninitialized, both strcpy operations are going to copy to the same array index.
Following code is not what you intended:
int names(char listName[][LEN])
{
int i;
strcpy(listName[i], "Vince");
strcpy(listName[i], "Jeremy");
}
void pass(char listPass[][LEN])
{
int i;
strcpy(listPass[i], "aBc2xyz8");
strcpy(listPass[i], "fa7saC12");
}
You should initialize i and increment it between the statements, or simply use:
int names(char listName[][LEN])
{
strcpy(listName[0], "Vince");
strcpy(listName[1], "Jeremy");
}
void pass(char listPass[][LEN])
{
strcpy(listPass[0], "aBc2xyz8");
strcpy(listPass[1], "fa7saC12");
}

Am I using structs in the wrong way?

I have come across this wierd and mysterous (at least to me) error that I am finding a very hard time finding. It gives me an error at the line where I call my function input(student_list1[MAX], &total_entries); where the compiler says:
incompatible type for agument 1 in 'input'
What am I doing wrong here? I sense it something very simple and stupid but I have gone through the code several times now without any avail.
#define MAX 10
#define NAME_LEN 15
struct person {
char name[NAME_LEN+1];
int age;
};
void input(struct person student_list1[MAX], int *total_entries);
int main(void)
{
struct person student_list1[MAX];
int total_entries=0, i;
input(student_list1[MAX], &total_entries);
for(i=0; i<total_entries; i++)
{
printf("Student 1:\tNamn: %s.\tAge: %s.\n", student_list1[i].name, student_list1[i].age);
}
return 0;
} //main end
void input(struct person student_list1[MAX], int *total_entries)
{
int done=0;
while(done!=1)
{
int i=0;
printf("Name of student: ");
fgets(student_list1[i].name, strlen(student_list1[i].name), stdin);
student_list1[i].name[strlen(student_list1[i].name)-1]=0;
if(student_list1[i].name==0) {
done=1;
}
else {
printf("Age of student: ");
scanf("%d", student_list1[i].age);
*total_entries++;
i++;
}
}
}
struct person student_list1[MAX] in the function argument is actually a pointer to struct person student_list1.
student_list1[MAX] you passed is a (out of bound) member of the array struct person student_list1[MAX]. Valid array index shoudl be between 0 to MAX - 1.
Change it to:
input(student_list1, &total_entries);
Note that here the array name student_list1 is automatically converted to a pointer to student_list1[0].
There are many things wrong with the code; this is my attempt at making it somewhat more robust:
#include <stdio.h>
#include <string.h>
#define MAX 10
#define NAME_LEN 15
// use a typedef to simplify code
typedef struct person {
char name[NAME_LEN];
int age;
} person_t;
// size qualifier on student_list is redundent and person_t* does the same
void input(person_t *student_list, int *total_entries);
int main(void)
{
person_t student_list[MAX];
int total_entries, i;
// pass array and not the non-existent 'student_list[MAX]' element
input(student_list, &total_entries);
for(i=0; i<total_entries; i++)
{
// age is an int, not a string so use %d
printf("Student 1:\tName: %s.\tAge: %d.\n", student_list[i].name, student_list[i].age);
}
return 0;
} //main end
void input(person_t *student_list, int *total_entries)
{
int done = 0, i = 0;
*total_entries = 0;
while (i < MAX) {
printf("Name of student: ");
// use NAME_LEN instead of strlen(list[i].name) because latter is
// probably not initialized at this stage
if (fgets(student_list[i].name, NAME_LEN, stdin) == NULL) {
return;
}
// detect zero-length string
if (student_list[i].name[0] == '\n') {
return;
}
printf("Age of student: ");
scanf("%d", &student_list[i].age);
// read the newline
fgetc(stdin);
*total_entries = ++i;
}
}
input(student_list1[MAX], &total_entries); shoud be input(student_list1, &total_entries);.
In C,
void input(struct person student_list1[MAX], int *total_entries);
equals
void input(struct person *student_list1, int *total_entries);

Resources