How can I assign to new values to static array in C? - c

Please advise me on how best to redeclare the array fields with new values using memcpy. If there's a better/optimum way to redeclare, please let me know that as well.
Here's my sample code:
#include <stdio.h>
#include <string.h>
#define array_size(array) sizeof(array)/sizeof(array[0])
struct user_profile {
const char *first_name;
const char *second_name;
unsigned int age;
};
int main() {
struct user_profile fields[] = {
{"david", "hart", 32},
{"billy", "cohen", 24},
};
for (int i = 0; i < array_size(fields); ++i) {
printf("%s %s\n", fields[i].first_name, fields[i].second_name);
}
memcpy(fields, {{"zach", "roberts", 59}, {"mike", "fisher", 19}}, sizeof(fields));
return 0;
}

You can, but you do not do this properly.
Using memcpy:
memcpy(fields, (struct user_profile[]){{"zach", "roberts", 59}, {"mike", "fisher", 19}}, sizeof(fields));
You can simply assign structures:
fields[0] = (struct user_profile){"zach", "roberts", 59};
fields[1] = (struct user_profile){"mike", "fisher", 19};
Both methods use compound literals

Related

Passing argument to a struct in C

I want to create the following struct.
struct student
{
char name[n+1];
int length = n;
};
Where n is a specific integer. Is it possible to pass an argument to a struct or another solution to achieve something like this? Maybe pointers. So I want different structs based on length.
You can use a flexible array member:
struct student {
int length;
char name[];
};
The struct is allocated and initialized for length n with:
struct student *s = malloc(sizeof *s + n + 1);
s->length = n;
// initialize s->name
strcpy(s->name, the_name_of_n_chars);
Remember to call free on s when it is no longer used.
Here is another implementation, apart from the other answers.
#include <string.h>
#include <stdlib.h>
struct student
{
char *name;
int length;
};
struct student *
alloc_student(char *name)
{
struct student *new;
new = malloc(sizeof(struct student));
if (new)
{
new->name = malloc(strlen(name)+1);
if (new->name)
{
new->length = strlen(name);
strcpy(new->name, name);
}
else
{
free(new);
new=NULL;
}
return new;
}
void
dealloc_student(struct student *s)
{
free(s->name);
free(s);
}
int
main(void)
{
struct student *s0;
s0 = alloc_student("John");
if (s0) dealloc_student(s0);
return 0;
}
Here is a way to have something like parameterized types, but I would not recommend that you do this! As you can see in the example below, it may not give you what you want and no extra safety. Better use the solution from tstanisl's answer.
You could use the C preprocessor to get different kinds of student structs with name arrays of different sizes. However, these will be distinct struct types, so the type of a student20 with char name[20 + 1] is related to the type of a student30 with char name[30 + 1].
#include <string.h>
#include <stdio.h>
#define DEFSTUDENT(n) struct student##n { \
char name[n+1]; \
int length; \
}
#define STUDENT(n) struct student##n
#define INIT_STUDENT(name) { name, strlen(name) }
DEFSTUDENT(100) student1 = INIT_STUDENT("John");
DEFSTUDENT(20) student2 = INIT_STUDENT("James");
DEFSTUDENT(1);
int main()
{
STUDENT(20) student3 = INIT_STUDENT("");
printf("%d\n", student3.length);
printf("%d\n", student2.length);
STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
printf("%d %s\n", impossibleStudent.length, impossibleStudent.name);
}
Note what the preprocessor makes out of this (I removed the #includes here for clarity):
C:\cygwin64\tmp\preproc>gcc -E student.c
# 1 "student.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "student.c"
# 11 "student.c"
struct student100 { char name[100 +1]; int length; } student1 = { "John", strlen("John") };
struct student20 { char name[20 +1]; int length; } student2 = { "James", strlen("James") };
struct student1 { char name[1 +1]; int length; };
int main()
{
struct student20 student3 = { "", strlen("") };
printf("%d\n", student3.length);
printf("%d\n", student2.length);
struct student1 impossibleStudent = { "Walter", strlen("Walter") };
printf("%d %s\n", impossibleStudent.length, impossibleStudent.name);
}
Here is what happens when I compile and run it:
C:\cygwin64\tmp\preproc>gcc student.c
student.c: In function 'main':
student.c:22:49: warning: initializer-string for array of chars is too long
STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
^
student.c:11:30: note: in definition of macro 'INIT_STUDENT'
#define INIT_STUDENT(name) { name, strlen(name) }
^~~~
student.c:22:49: note: (near initialization for 'impossibleStudent.name')
STUDENT(1) impossibleStudent = INIT_STUDENT("Walter");
^
student.c:11:30: note: in definition of macro 'INIT_STUDENT'
#define INIT_STUDENT(name) { name, strlen(name) }
^~~~
C:\cygwin64\tmp\preproc>a.exe
0
5
6 Wa#

Swapping struct array elements

I have difficulty applying the pass by reference and pass by value separation in structs.How can I swap the elements of the fixed size struct array as below.
struct try{
int num;
char name[10];
};
int main(){
struct try book[3];
void swapper(/********/);// <-what should be the argument of this function
}
void swapper(/********/){//swap second and third element of struct array
/*how the swap may be done?
temp=book[2];
book[2]=book[3];
temp=book[3];*/
}
There are a lot of ways to do what you're asking. One approach:
#include <stdio.h>
struct try {
int num;
char name[10];
};
void
swapper(struct try *a, int b, int c)
{
struct try tmp = a[b];
a[b] = a[c];
a[c] = tmp;
}
void
display(const struct try *t, size_t count)
{
while( count-- ){
printf("%d: %s\n", t->num, t->name);
t += 1;
}
}
int
main(void) {
struct try book[] = {
{ 1, "foo"},
{ 2, "bar"},
{ 3, "baz"}
};
display(book, sizeof book / sizeof *book);
swapper(book, 1, 2);
display(book, sizeof book / sizeof *book);
return 0;
}

How to print from struct in C, I'm not sure what I'm doing wrong and keep getting various errors from all parts of the code?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define SIZE 25
#define NUM_EMP 3
void printEmployees (Employees [NUM_EMP], int c);
typedef struct employee
{
char fname[20];
char lname[20];
int id;
char dependents [3][20];
} Employees;
void printEmployees(Employees [NUM_EMP], int c) {
//a function to print what's written in the struct
printf("%s", Employees[0].fname);
printf("%s", Employees[0].lname);
printf("%d", Employees[0].id);
printf("%s", Employees[0].dependents);
}
int main() {
//populating the struct above
Employees[NUM_EMP] {
{"Juan", "Libero", 1, {"son", "daughter", "dog"}},
{"Stan", "Smith", 2, {"daughter", "daughter", "dog"}},
{"Russell", "Green", 3, {"son", "son", "cat"}},
}
Employees [NUM_EMP];
printEmployees(Employees,3);
}
I'm doing a project right now, my goal is to print what I have under main(), which is information that I tried to put into the struct, which cannot be changed. I just want to print the information I have in main, from the struct, but keep getting errors and I don't know how to fix it. Is there anyone that can help me?
Problem is there is no struct variable. Employees is just a type, used as an abbreviation for struct employee, this will work:
void printEmployees(Employees persons[], int c);
void printEmployees(Employees persons[], int c) {
//a function to print what's written in the struct
printf("%s ",persons[0].fname);
printf("%s ", persons[0].lname);
printf("%d ", persons[0].id);
printf("%s\n", persons[0].dependents);
}
int main() {
//populating the struct above
Employees persons[NUM_EMP] = {
{"Jackson", "Leverock", 1, {"son", "daughter", "dog"}},
{"Stan", "Smith", 2, {"daughter", "daughter", "dog"}},
{"Russell", "Green", 3, {"son", "son", "cat"}},
};
printEmployees(persons,3);
}
Your typedef implies something's an array but it is not. Make it singular:
typedef struct employee
{
char fname[20];
char lname[20];
int id;
char dependents [3][20];
} Employee;
Then declare an array of them later:
Employee employees[NUM_EMP] = { ... };
Note using lower-case for variable names.

What is best solution for initialize struct array?

First solution:
struct str {
char *name;
int flag;
};
enum {
HELP,
OUTPUT,
OTHER
};
typedef struct str table;
table arr[] = {
{ "help", HELP },
{ "output", OUTPUT },
{ NULL, OTHER },
};
int main(int argc, char **argv) {
table *opt = arr;
printf("%s\n", (opt+HELP)->name);
printf("%s\n", (opt+OUTPUT)->name);
return 0;
}
Second solution:
struct str {
char *name;
int flag;
};
enum {
HELP,
OUTPUT,
OTHER
};
typedef struct str table;
table arr[OTHER];
void start_table() {
arr[HELP] = (struct str) { "help", HELP };
arr[OUTPUT] = (struct str) { "output", OUTPUT };
arr[OTHER] = (struct str) { NULL, OTHER };
}
int main(int argc, char **argv) {
start_table();
table *opt = arr;
printf("%s\n", (opt+HELP)->name);
printf("%s\n", (opt+OUTPUT)->name);
return 0;
}
What are the best? Second solution change automatically if I add or change any element of the array, but is efficient? Is the best enumerate or using the #define preprocessor directive?
It depends!
When initialization can be used, use it — so the first solution is often better, especially if the code never changes the structure (array) contents.
If your code can change the contents but might need to be able to reset to the original state, then the initialization function becomes more appropriate and using direct initialization is not appropriate.
There is no one 'best' solution; what is best depends on what you need to do with the array.
Using a C99 specific intializer syntax, you can get the advantages of the second approach in a static initializer:
#include <stdio.h>
struct str {
const char *name;
int flag;
};
enum {
HELP,
OUTPUT,
OTHER,
};
typedef struct str table;
table arr[] = {
[HELP] = { "help", HELP },
[OUTPUT] = { "output", OUTPUT },
[OTHER] = { NULL, OTHER },
};
int main(int argc, char **argv) {
table *opt = arr;
printf("%s\n", opt[HELP].name);
printf("%s\n", opt[OUTPUT].name);
return 0;
}
The advantage of this technique is it makes no assumption on the order of the enum values, nor on their actual values as long as they are positive, distinct and reasonably small.

Access element of array of pointer of structure

I want to access the element of array of pointer to structure but i have no idea how to access it.
#include<stdio.h>
int main()
{
struct hash
{
int pages;
int price;
};
struct hash *h[5]={1,2,3,4,5};//array of pointer to structure
printf("value =%d\n",h->pages);
// want to access and also tell me how to data will be write
}
How we will access the element I tried it through pointer but it's showing error
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct hash {
int pages;
int price;
};
struct hash *h[2];
h[0] = malloc(sizeof(struct hash));
h[0]->pages = 1;
h[0]->price = 2;
h[1] = malloc(sizeof(struct hash));
h[1]->pages = 3;
h[1]->price = 4;
printf("value = %d\n", h[0]->pages);
}
Here is a sample that compiles. Maybe this helps you get started.
#include <stdio.h>
#include <stdlib.h>
struct hash
{
int pages;
int price;
};
struct hash h[5]=
{
{ 1, 1 },
{ 2, 2 },
{ 3, 3 },
};
int main(void)
{
printf("pages: %d\n", h[0].pages);
printf("pages2: %d\n", h[1].pages);
return EXIT_SUCCESS;
}
I would first suggest trying to get a stuct hash *h; to point to a single variable. Once that works, you should build upon it to get the array of struct hash *h[5] to work.

Resources