I'm trying to print out all the members of each structure from a list. I was provided the print functions below to print out an element from a generic list.
Here is the structure definition of my list, which is in a generic list ADT c file:
struct list_type {
void *data;
int size;
int capacity;
int elementSize;
int (*comparePtr) (void *d1, void *d2);
};
So in a generic list ADT c file, I have this print function:
// client needs to send a pointer to a function capable of printing an element
void printl(ListType listptr, void (*printItem) (void *d)) {
int i;
for(i = 0; i < listptr->size; i++) {
// since we cannot use data[i], we need to calculate the address
// of the element to be sent to the client's print function
// since data is of type void, the formula is:
// the beginning address of the array + (offset x element size)
printItem(listptr->data + i * (listptr->elementSize) );
printf(" ");
}
printf("\n");
}
I call my printl function like so:
printl(clientList, printItem);
In my driver file, there's a function to print out an element from the list:
void printItem (int* p) {
printf("%d", *p);
//`my attempt at printing the members of an individual structure from the list
// printf("%s", ((Client *)&p)[0]);
}
Here is my Client structure definition:
struct client_tag {
char id[5];
char name[30];
char email[30];
char phoneNum[15];
};
When I run the program, I get a bunch of weird characters. How do I fix this?
Assuming you left out the line
typedef struct client_tag Client;
and assuming the strings of Client are guaranteed to be null terminated, this is the idea:
void printItem (const Client* p) {
printf("%s\n", p->id);
}
Related
I'm trying to pass data of a struct between the main and another function (on a different file .c) with no success. I have a struct like this
struct player{
char name[10];
int budget;
};
typedef struct player Player;
void PrintFunc(Player p); //function prototype
Player gamer[2] = {{"Alice", 100},
{"Bob", 100 }};
And I call it from the main func with something like
PrintFunc(gamer);
The function structure should be something like this
void PrintFunc(Player p){
//stuff
}
What am I doing wrong?
gamer is an array, PrintFunc expects a single object.
Option 1:
PrintFunc(gamer[0]);
PrintFunc(gamer[1]);
Option 2: change the function to accept a pointer to Player objects:
void PrintFunc(Player *p, size_t len){
for(size_t i = 0; i < len; ++i)
// do something with p[i]
}
int main(void)
{
Player gamer[2] = {{"Alice", 100},
{"Bob", 100 }};
PrintFunc(gamer, sizeof gamer / sizeof *gamer);
return 0;
}
void PrintFunc(Player p[]){
//stuff
}
Receive array of player objects when sending array of player objects
I have the following code:
if (strcmp(method, "print") == 0){
for (i = 0; i < hashtable->M; i++){
fprintf(fout,"[%d] :", i);
if (hashtable->v[i] != NULL)
while(hashtable->v[i]){
fprintf(fout," ");
((Pair*)hashtable->v[i]->info)->fp(hashtable->v[i], fout);
hashtable->v[i] = hashtable->v[i]->urm;
}
fprintf(fout,"\n");
}
}
In my code, when I encounter a "print" from the file, I have to print out the values stored in my hashtable. M is the size of the hashtable, while v is a void* which points to a linked list. It's all good but if I have to add some values in the hashtable and then print them, after printing I lose all the previously stored values. I think this might have to do with the fact that I'm doing this: hashtable->v[i] = hashtable->v[i]->urm; but even so, I don't know how to recover the values. I was thinking about something as an auxiliary pointer to the hashtable, but that failed for me. Note, the structures are as follow
typedef struct celulag {
void *info;
struct celulag *urm;
} TCelulaG, *TLG, **ALG;
typedef unsigned int (*TFHash)(const void*, size_t M, size_t range);
/* structura tabela Hash */
typedef struct {
size_t M;
TFHash fh;
TLG *v;
} TH;
typedef void (*TPrint)(TLG l, FILE *g);
typedef struct {
void *key;
void *value;
TPrint fp;
int frequency;
} Pair;
Note that this is done in a while so the assignment would look as this:
Add 3 values, print, add another 4 values, print. After adding the first 3 values, if I prind, it's all good, after adding the next 4 values, if I print, only the last 4 values appear.
Can anyone help? Thank you very much.
I am trying to sort an array of pointers to structs (definition below) based on the value stored in the void* of the "bucket" struct that I know are ints. It compiles and prints out my array of buckets and their values just fine with no errors or warnings but it isn't actually sorting the array. I have used asserts to try to find anywhere that could cause an error with qsort.
Struct definitions:
typedef struct _bucket{
void* val;
char *word;
}bucket;
typedef struct _root{
bucket **list;
int hashTableLength;
}root;
Sort Function to be passed to the qsort function:
int sortFunc(const void *a, const void *b){
bucket *bucketA=(bucket*)a;
bucket *bucketB=(bucket*)b;
int bucketAVal = *((int*)bucketA->val);
int bucketBVal = *((int*)bucketB->val);
assert((bucketAVal&&bucketBVal)!=0);
return bucketAVal-bucketBVal;
}
Sort the array and print:
void sort(root* inRoot, int(*sortFunc)(const void *a, const void *b)){
int length = inRoot->hashTableLength;
assert(length==11); //known length of hash array
for (int i = 0; i<length; i++)
assert(inRoot->list[i] != NULL);
qsort(inRoot->list, length, sizeof(bucket*), sortFunc);
for(int i =0; i<length; i++)
printf("%s was found %d times\n", inRoot->list[i]->word, *((int*)(inRoot->list[i]->val)));
return;
}
The compare function sortFunc() receives a pointer to each object. The array inRoot->list is an array of bucket * so sortFunc() is receiving pointers to bucket *: bucket **.
Also the int subtraction is subject to possible overflow. Use the idiomatic 2 compares to solved that.
int sortFunc(const void *a, const void *b) {
bucket **bucketA = (bucket**) a;
bucket **bucketB = (bucket**) b;
void *vA = (*bucketA)->val;
void *vB = (*bucketB)->val;
int iA = *((int*) vA);
int iB = *((int*) vB);
return (iA > iB) - (iA < iB);
}
How should I parse an array of structures as parameter to a function?
For example, I have the following structure definition:
struct Town
{
char *TownName;
char **GiftList;
int *GiftCount;
int GiftTypes;
};
and a declaration of an array of such structures, in my main:
struct Town TownList[100];
struct Town AuxiliaryStructure;
I have written a custom sorting function for this array, in which I want to make use of each structure's fields, but I do not know how to provide the array TownList[100] to the sort function.
To pass an array of anything to a function, you can just pass a pointer to the first element plus an array length:
struct mystruct {
char* something;
/* ... */
}
struct mystruct myarray[100];
void do_something(struct mystruct* array, int length)
{
int i;
for (i=0; i<length; ++i)
{
array[i].something = ...
}
}
int main(void)
{
do_something(myarray, 100);
return 0;
}
Based on what you wrote, you would reference it in the caller and pass the result. For example:
void sort(char* str){
...
}
int main(){
for(int i=0; i<100; ++i){
sort(array[i].something);
}
}
Alternately you may want to pass the full array and handle it in another function, which would be like this:
void sort(struct mystruct * array){
...
}
int main(){
for(int i=0; i<100; ++i){
sort(array);
}
}
If, on the other hand, you meant that you want to sort the outer array of structures by the contents of something, then you would either have to pass the array as above and implement your own sort, or use a sorting function that takes a function pointer so you can write a comparator. The latter is available in the standard C library, and could be used something like this.
#include <stdlib.h>
int compare_mystruct_by_something(const void *a, const void *b){
return strcmp(((struct mystruct*)a)->something, ((struct mystruct *)b)->something);
}
int main(){
qsort(array, 100, sizeof(struct mystruct), compare_mystruct_by_something);
}
For the below code
struct orderSlip
{
char source[64];
char destination[64];
char item[64];
int position;
};
//global
struct orderSlip data[100];
Is there another way of printing out the data for each element other than these methods below:
printf("%s\n",data[0].source);
printf("%s\n",data[0].destination);
printf("%s\n",data[0].item);
printf("%i\n\n", data[0].position);
printf("%s\n",data[1].source);
printf("%s\n",data[1].destination);
printf("%s\n",data[1].item);
printf("%i\n", data[1].position);
etc
for(int n = 0; n< 3; n++)
{
printf("%s\n",data[n].source);
printf("%s\n",data[n].destination);
printf("%s\n",data[n].item);
printf("%i\n\n", data[n].position);
}
For deleting and adding, do I have to make a dynamic array of structs? If so, what would be the simplest syntax to do that?
Something like this c++ code
int * bobby;
bobby = new int [5];
delete bobby[5];
but in C? I'm guessing it has do with malloc and free
"For deleting and adding, do I have to make a dynamic array of structs? If so, what would be the simplest syntax to do that? Something like this c++ code"
Not if you know that you will never have more than x amount of items or at least check to make sure you aren't exceeding what you planned was the max. Then you can use your static array.
Adding only requires you to have a variable that keeps track of how many items are in the array:
void add_item(struct orderSlip *p,struct orderSlip a,int * num_items)
{
if ( *num_items < MAX_ITEMS )
{
p[*num_items] = a;
*num_items += 1;
}
}
Deleting from a static array would require a for loop that would move the items above it down one and decrementing the int keeping track of the number of items.
void delete_item(struct orderSlip *p,int *num_items, int item)
{
if (*num_items > 0 && item < *num_items && item > -1)
{
int last_index = *num_items - 1;
for (int i = item; i < last_index;i++)
{
p[i] = p[i + 1];
}
*num_items -= 1;
}
}
You could simplify printing the struct by passing it to a function that does the work.
void print(const struct orderSlip *p);
or
void print(const struct orderslip s);
optionally
void print(const struct orderslip s, FILE *fp);
or
void print(const struct orderslip *p, FILE *fp)
{
fprintf(fp,"%s\n",p->source);
...
}
and
void print_all(const struct orderSlip *p, int num_items)
//global
struct orderSlip data[MAX_ITEMS];
int num_items = 0;
int main(void)
{
...
print_all(data,num_items);
strcpy(a.source,"source 2");
strcpy(a.destination,"destination 20");
strcpy(a.item,"item xyz");
a.position = 99;
add_item(data,a,&num_items);
print_all(data,num_items);
delete_item(data,&num_items,0);
print_all(data,num_items);
One way is to allocate each element in your array and just keep an array of pointers
struct orderSlip **data;
data = calloc(100, sizeof(struct orderSlip*)); // 100 pointers to struct
(calloc will make sure memory is zero:ed from the start)
everytime you add a new struct:
data[i] = calloc(1, sizeof(struct orderSlip));
and when you don't need any longer
free(data[i]);
You can also change the size of data by using realloc, see
If you don't need to access the array using index, you could instead consider another type of data structure like a linked list to be truly dynamic.