creating a generic array taken from an array of structures - c

I need to pass to qsort a generic array. That array must be taken from the colons of a file structured like this:
int,string,int,float.
I've created an appropriate struct type but I'm having troubles creating a dinamically allocated array of structures.
here I created an array of pointers to structures
struct *p_structure=malloc(n_records*sizeof(struct record_type*));
and then I have no idea on what to do :(
Any help would be really appreciated, thanks
PS I calculated the n_records in advance

I've created an appropriate struct type but I'm having troubles creating a dinamically allocated array of structures.
Assuming this is your struct:
struct record {
int i1;
char *s;
int i2;
float f;
};
This should be the array declaration:
struct record *array = malloc(sizeof(*array) * n_records);
and then I have no idea on what to do
In case you didn't do it already, you need to parse the file (see Appendix).
Once parsed, you have to define how your array items should compare against each another. In other words, what are the criteria that should be taken into consideration to compare (and of course, sort) your items. Programmatically, you need to provide a function that does that. That function's signature must match the signature of the function that qsort accepts as argument. For example (considering i1 as the comparison criteria):
int compare_record(const void *p1, const void *p2)
{
const struct record *r1 = p1;
const struct record *r2 = p2;
if (r1->i1 > r2->i1)
return 1;
if (r1->i1 < r2->i1)
return -1;
return 0;
}
Now, calling qsort becomes straightforward:
qsort(array, n_records, sizeof(*array), compare_record);
Appendix
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct record {
int i1;
char *s;
int i2;
float f;
};
int compare_record(const void *p1, const void *p2)
{
const struct record *r1 = p1;
const struct record *r2 = p2;
if (r1->i1 > r2->i1)
return 1;
if (r1->i1 < r2->i1)
return -1;
return 0;
}
int main(void)
{
int n_records = 3;
FILE *file = fopen("filename.txt", "r");
if (!file) {
printf("Opening file failed.\n");
exit(EXIT_FAILURE);
}
struct record *array = malloc(sizeof(*array) * n_records);
if (!array) {
printf("An internal error has occurred.\n");
exit(EXIT_FAILURE);
}
int index = 0;
char line[1024]; // Large enough to hold a line?
int i1, i2;
float f;
char s[256];
while (fgets(line, sizeof line, file)) { // PS I calculated the n_records in advance
if (sscanf(line, "%d,%255[^\n,],%d,%f", &i1, s, &i2, &f) != 4) {
// Problematic line...
printf("Problematic line %d...\n", index+1);
}
array[index].i1 = i1;
array[index].s = strdup(s);
array[index].i2 = i2;
array[index].f = f;
++index;
printf("%d | %s | %d | %f\n", i1, s, i2, f);
}
fclose(file);
qsort(array, n_records, sizeof(*array), compare_record);
for (int i = 0; i < n_records; ++i)
printf("%d | %s | %d | %f\n", array[i].i1, array[i].s, array[i].i2, array[i].f);
// Don't forget to free the memory allocated by strdup().
}

It seems that you just created a structure pointer but you don't give it a variable name.
Try this:
struct p_structure *your_var_name =malloc(n_records*sizeof(struct record_type*));
If it won't work, could you provide the code of your structures please ?

Related

Hash Table in C (find the frequency of every word)

I want to create a hash table for an exercise I have to send in my University.
The program will open a number of files, break each file's content to <<words>> (tokens) and it will save each <<word>> in a hash table with the frequency of each <<word>>.
In case the word is already in the hash table , the program will increase the word's frequency.
At the end the program will print the words and it's frequencies accordingly.
Also the frequencies should be printed from the highest word frequency to the lowest.
The comparison of the <<words>> will ignore upper and lower case letters.
For example if a file contains : one two three four Two Three Four THREE FOUR FoUr
It should print:
four 4
three 3
two 2
one 1
The professor gave us a template that we should complete but I'm really confused on what to do with the insert_ht() and clear_ht() functions as well as the compare one.
Here is the code :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
for (i=1; i < argc; i++)
{
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
Process(fp);
fclose(fp);
}
print_ht();
clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators))
insert_ht(s);
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
……………………………………………
}
void clear_ht()
{
……………………………………………
}
int compare(const void *elem1, const void *elem2)
{
……………………………………………
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
I'll answer you in a new post because it's hard to be exhaustive in comments.
1. Malloc
Why would I need to use malloc then ? Shouldn't i write directly to the htable? (on the insert_ht() funtion)
You need to use malloc because you declare a char pointer in struct (char *token). The thing is that you never initialize the pointer to anything, and as far you don't know the size of the token, you need to malloc every token. But, as you use strdup(token), you don't need to malloc token because strdup does. So don't forget to free every token in order to avoid memory leaks.
2. Segfault
I can't test you code, but it seems like the following line causes the segmentation fault :
list = htable[hashval]->token
Indeed, you try to access token while htable[hashval] is NULL, and to assign a char * to a link type (list).
You need to loop with this :
for(list = htable[hashval]; list != NULL; list = list->next) { ... }
3. Notes
if (x=1) should be if(x==1).
Don't malloc new_list if you don't need to.
Because new_list if used when htable[hashval] is NULL, new_list->next = htable[hashval]; will set new_list->next to NULL.
You should use the -Wall option in gcc (for warnings) and you may use valgrind to understand your segmentation faults. In this case, use gcc with debug mode (-g).
Double and Final edit : Ι found the solution. Apparently for some reason my compare function was wrong.
I still haven't figured out why but here is the correct one, hopefully someone else will find this post helpful!
int compare(const void *elem1, const void *elem2)
{
return (*(link*)elem2)->freq - (*(link*)elem1)->freq;
}
Edit: deleted old answer . Found the correct way I think but I have another problem right now.
The compare function doesn't work correctly. My printf is fine but it doesnt sort them with the frequiencies. I want them to be sorted from the highest to lowest .
In this example: the file contains -> one two three four Two Three Four THREE FOUR FoUr
And I get:
two 2
one 1
four 4
three 3
While I should be getting :
four 4
three 3
two 2
one 1
Here is the code. Feel free to help!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define HTABLE_SIZ 1001
#define MAX_LINE_SIZ 1024
/* Hash Table */
typedef struct node* link;
struct node { char *token; int freq; link next; };
link htable[HTABLE_SIZ] = { NULL }; /* Table of lists (#buckets) */
int size = 0; /* Size (number of elements) of hash table */
unsigned int hash (char *tok );
void insert_ht (char *data);
void clear_ht ( );
void print_ht ( );
void Process(FILE *fp);
int main(int argc, char *argv[])
{
int i;
FILE *fp;
printf("prin tin for \n");
for (i=1; i < argc; i++)
{
printf("prin tin fopen \n");
fp = fopen(argv[i],"r");
if (NULL == fp)
{
fprintf(stderr,"Problem opening file: %s\n",argv[i]);
continue;
}
printf("prin tin process \n");
Process(fp);
fclose(fp);
}
print_ht();
//clear_ht();
return 0;
}
void Process(FILE *fp)
{
const char *seperators = " ?!'\";,.:+-*&%(){}[]<>\\\t\n";
char line[MAX_LINE_SIZ];
char *s;
while((fgets(line,MAX_LINE_SIZ, fp)) != NULL)
{
for (s=strtok(line,seperators); s; s=strtok(NULL,seperators)){
printf("prin tin insert %s \n",s);
insert_ht(s);
}
}
}
/* Hash Function */
unsigned int hash(char *tok)
{
printf("bike stin hash \n");
unsigned int hv = 0;
while (*tok)
hv = (hv << 4) | toupper(*tok++);
printf("VGAINEIIIIIIIIIIIIII %d \n",hv);
return hv % HTABLE_SIZ;
}
void insert_ht(char *token)
{
printf("bike stin insert %s \n",token);
unsigned int hashval = hash(token);
if (htable[hashval]==NULL){
printf("mesa stin prwti if %u %s \n",hashval,token);
//token = strdup(token);
htable[hashval] = malloc(sizeof(token));
htable[hashval]->token = token ;
htable[hashval]->freq = 1;
size++;
}else {
htable[hashval]->freq++;
}
printf("ta evale epitixws \n");
}
int compare(const void *elem1, const void *elem2)
{
const struct node *p1 = elem1;
const struct node *p2 = elem2;
if ( p1->freq < p2->freq)
return -1;
else if (p1->freq > p2->freq)
return 1;
else
return 0;
}
void print_ht()
{
int i, j=0;
link l, *vector = (link*) malloc(sizeof(link)*size);
for (i=0; i < HTABLE_SIZ; i++)
for (l=htable[i]; l; l=l->next)
vector[j++] = l;
qsort(vector,size,sizeof(link),compare);
for (i=0; i < size; i++)
printf("%-50s\t%7d\n",vector[i]->token,vector[i]->freq);
free(vector);
}
Sorry for my bad english.
I think that :
insert(char *token) takes a word of the file and puts into the hash table. In brief, if the word exists in the hash table, you just have to increment its frequencie. Otherwise, you need to create another node and put the frequencie to 1, then ad it to the array. At the end, you will have one entry for each unique word.
compare(const void *elem1, const void *elem2) will be used by qsort. It returns 0 if elem1 = elem2, a negative number if elem1 < elem2 and a number > 0 if elem1 > elem2. By passing compare to qsort, you allow qsort to sort you array according to your own criteria.
clear_ht() may set all the values of the array to NULL, in order to restart another count ?

Struct arrays in C

Hi I'm having trouble trying to initializing each element of the struct array. When I try and assign the value ZERO to both 'bSize' and 'msgs', it doesn't work as it errors out when i get to malloc. In the printf statement it prints a -1852803823 number. Excuse the messy code as i'm playing around trying to figure it out.
struct message{
int *data;
int bSize;
int msgs;
};
int main(int argc, char *argv[]) {
.....
}
void getSchedFile (FILE *file, int **schd) {
struct message sMsg[nodeCount];
const int pakSize = 6;
// Iniitialise message buffer
for (int i=0; i<nodeCount; i++){
sMsg[i].bSize = 0;
sMsg[i].msgs = 0;
printf("bSize %d\n",sMsg[i].bSize);
}
/* Get the number of bytes */
fseek(file, 0L, SEEK_SET);
int time;
while((fscanf(file, "%d", &time)) != EOF){
int src;
fscanf(file, "%d", &src); // get source node id
// These are here for easier reading code
int aPos = sMsg[src].bSize;
int nMsg = sMsg[src].msgs;
printf("size %d\n", sMsg[src].bSize);
if (sMsg[src].bSize==0){
sMsg[src].data = malloc( pakSize * sizeof(int));
}else{
sMsg[src].data = realloc(sMsg[src].data, (aPos+pakSize)*sizeof(int));
}
Where is the nodeCount value coming from? Is it a global variable? You should be very careful with global variables, and avoid using them if possible.
Pass the nodeCount in the method parameter and as Charlie mentioned, check it for > 0

How do I unpack and extract data properly using msgpack-c?

I'm currently trying to use msgpack in a project written in C. I'm using msgpack for the purpose of serializing the contents of a struct, which is then to be sent over the network, and deserialized back into a corresponding struct on the other side.
Condensed version of what I'm trying to do:
#include <stdio.h>
#include <msgpack.h>
#include <stdbool.h>
typedef someStruct{
uint32_t a;
uint32_t b;
float c;
} someStruct;
int main (void){
someStruct data;
/* ... Fill 'data' with some data for test purposes ...*/
msgpack_sbuffer* buff = msgpack_sbuffer_new();
msgpack_packer* pck = msgpack_packer_new(buff, msgpack_sbuffer_write);
someStruct* structs = malloc(sizeof(someStruct) * 10);
/* ... Fill 'structs' with members containing test data ... */
// Serialize
msgpack_pack_array (pck, 10);
int i;
for(i = 0 ; i < 10 ; i++){
msgpack_pack_array (pck, 3);
msgpack_pack_uint32 (pck, structs[i].a);
msgpack_pack_uint32 (pck, structs[i].b);
msgpack_pack_float (pck, structs[i].c);
}
free(structs);
msgpack_packer_free(pck);
// Deserialize
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
bool deserialize_success = msgpack_unpack_next
(&msg, buff->data, buff->size, NULL);
if(!deserialize_success) /* Error */
msgpack_object obj = msg.data;
msgpack_object_print(stdout,obj); // This seems to work perfectly, indicating serialize / deserialize works as intended...
someStruct deserialized_data;
/* Insert code to extract and cast deserialized data to 'deserialized_data */
// Clean
msgpack_sbuffer_free(buff);
msgpack_packer_free(pck);
return 0;
}
The code listed is more or less ripped straight from here, which seems to be one of very few resources on msgpack-c.
Can anyone point me in the right direction as to a way to 'recreate' the original struct on the other side of the wire? The only way I've found to actually utilize the deserialized data, is to use the msgpack_object_print() call to print from the messagepack_object. This does, however seem to work, so I'm certain the data is there.
Do I need to somehow loop through the serialized data and use msgpack_unpack_next() with an offset to retrieve each someStruct member? Using memcpy to a local byte buffer?
Any help is greatly appreciated!
Please find below a rewritten version that illustrates how to pack / unpack your data.
The whole idea is to pack each successive field of your struct, in a contiguous fashion, and apply (of course), the same logic at unpack time.
Right after pack, you are free to use the buffer the way you want (e.g send over the network, save on-disk, etc).
#include <stdio.h>
#include <assert.h>
#include <msgpack.h>
typedef struct some_struct {
uint32_t a;
uint32_t b;
float c;
} some_struct;
static char *pack(const some_struct *s, int num, int *size);
static some_struct *unpack(const void *ptr, int size, int *num);
/* Fixtures */
some_struct ary[] = {
{ 1234, 5678, 3.14f },
{ 4321, 8765, 4.13f },
{ 2143, 6587, 1.34f }
};
int main(void) {
/** PACK */
int size;
char *buf = pack(ary, sizeof(ary)/sizeof(ary[0]), &size);
printf("pack %zd struct(s): %d byte(s)\n", sizeof(ary)/sizeof(ary[0]), size);
/** UNPACK */
int num;
some_struct *s = unpack(buf, size, &num);
printf("unpack: %d struct(s)\n", num);
/** CHECK */
assert(num == (int) sizeof(ary)/sizeof(ary[0]));
for (int i = 0; i < num; i++) {
assert(s[i].a == ary[i].a);
assert(s[i].b == ary[i].b);
assert(s[i].c == ary[i].c);
}
printf("check ok. Exiting...\n");
free(buf);
free(s);
return 0;
}
static char *pack(const some_struct *s, int num, int *size) {
assert(num > 0);
char *buf = NULL;
msgpack_sbuffer sbuf;
msgpack_sbuffer_init(&sbuf);
msgpack_packer pck;
msgpack_packer_init(&pck, &sbuf, msgpack_sbuffer_write);
/* The array will store `num` contiguous blocks made of a, b, c attributes */
msgpack_pack_array(&pck, 3 * num);
for (int i = 0; i < num; ++i) {
msgpack_pack_uint32(&pck, s[i].a);
msgpack_pack_uint32(&pck, s[i].b);
msgpack_pack_float(&pck, s[i].c);
}
*size = sbuf.size;
buf = malloc(sbuf.size);
memcpy(buf, sbuf.data, sbuf.size);
msgpack_sbuffer_destroy(&sbuf);
return buf;
}
static some_struct *unpack(const void *ptr, int size, int *num) {
some_struct *s = NULL;
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
if (msgpack_unpack_next(&msg, ptr, size, NULL)) {
msgpack_object root = msg.data;
if (root.type == MSGPACK_OBJECT_ARRAY) {
assert(root.via.array.size % 3 == 0);
*num = root.via.array.size / 3;
s = malloc(root.via.array.size*sizeof(*s));
for (int i = 0, j = 0; i < root.via.array.size; i += 3, j++) {
s[j].a = root.via.array.ptr[i].via.u64;
s[j].b = root.via.array.ptr[i + 1].via.u64;
s[j].c = root.via.array.ptr[i + 2].via.dec;
}
}
}
msgpack_unpacked_destroy(&msg);
return s;
}

How to pass struct array into a function and correctly store value in it?

I would like to read a file that has the sample number, values and status(1.1, 23,0). I used a Struct to hold that information. I will pass the function struct array and the file location.
#include <stdio.h>
struct Data_point
{
long sampleNumber;
double value;
int status;
};
int filldata(struct Data_point *a, const char *filelocation)
{
FILE *f;
if((f=fopen(filelocation,"r"))==NULL)
{
printf("You cannot open");
}
fscanf(f, "%ld%lf%d", a.sampleNumber, a.value, a.status);
}
int main(void)
{
struct Data_point data[10];
filldata(data, "/home/alexchan/IntrotoC/rec11/dataPoints.txt");
return 0;
}
But, I got an error saying, "request for member not a structure"...
One problem is that the filldata() is taking a pointer argument. So you use -> to address members not ".". So a.sampleNumber should be a->sampleNumber for example.
Another issue is that filldata() is reading in a single struct, but you are passing it the pointer to the top of the array, which is synonymous with &(data[0]). So this function will just overwrite that first element if you call it repeatedly (which you didn't). If you call it in a loop you will need to pass it in pointers to the individual array members:
for(int i = 0; i < 10; ++i){
filldata(&(data[i]), "/home/alexchan/IntrotoC/rec11/dataPoints.txt");
}
You could actually use data + i as the first arg instead of &(data[i]) but I like the latter as I find it more readable.
struct Data_point *a is your function arugument and you are passing data which is a array. So basically you are trying to acess members from a array which is not a struct.
May be
for( int i=0; i<10;++i)
filldata(data[i],.....)
and
int filldata( struct Data_point a,...) //as you are using a.
fscanf requires a pointer-to-data for each passed argument. Use the AddressOf operator & to get a reference to each struct member:
int filldata(const char *filelocation, struct Data_point *a, int nElements)
{
int n = 0;
FILE *f = fopen(filelocation, "r");
if(f)
{
while (fscanf(f, "(%ld,%lf,%d)", &(a[n].sampleNumber), &(a[n].value), &(a[n].status)) == 3 && n < nElements)
n++;
fclose(f);
}
else { printf("Unable to open '%s'\n", filelocation); }
return n;
}
Now, this function is slightly different to yours. You need to tell it how long the array you're passing in as the "a" parameter is. It will return the number of successfully filled entries.
i.e
int main(int argc, char **argv)
{
struct Data_point data[10];
int n = filldata("C:\\Users\\254288b\\temp.txt", data, sizeof(data) / sizeof(struct Data_point));
printf("%d Data_point's were filled successfully.\n\n", n);
for(int i = 0; i < n; i++)
{
printf("Sample Number: %ld\n", data[i].sampleNumber);
printf("Value: %lf\n", data[i].value);
printf("Status: %d\n", data[i].status);
printf("----------------------------\n");
}
return 0;
}
Do note, my pattern for fscanf expects your file to be like:
(100,1.1,10)(200,2.2,20)(300,3.3,30)(400,4.4,40)
Each set is enclosed in parenthesis.

returning multiple values from a function [duplicate]

This question already has answers here:
How do I return multiple values from a function in C?
(8 answers)
Closed 3 years ago.
Can anyone tell me how to return multiple values from a function?
Please elaborate with some example?
Your choices here are to either return a struct with elements of your liking, or make the function to handle the arguments with pointers.
/* method 1 */
struct Bar{
int x;
int y;
};
struct Bar funct();
struct Bar funct(){
struct Bar result;
result.x = 1;
result.y = 2;
return result;
}
/* method 2 */
void funct2(int *x, int *y);
void funct2(int *x, int *y){
/* dereferencing and setting */
*x = 1;
*y = 2;
}
int main(int argc, char* argv[]) {
struct Bar dunno = funct();
int x,y;
funct2(&x, &y);
// dunno.x == x
// dunno.y == y
return 0;
}
You can't do that directly. Your options are to wrap multiple values into a struct, or to pass them in as pointer arguments to the function.
e.g.
typedef struct blah
{
int a;
float b;
} blah_t;
blah_t my_func()
{
blah_t blah;
blah.a = 1;
blah.b = 2.0f;
return blah;
}
or:
void my_func(int *p_a, float *p_b)
{
*p_a = 1;
*p_b = 2.0f;
}
First of all, take a step back and ask why you need to return multiple values. If those values aren't somehow related to each other (either functionally or operationally), then you need to stop and rethink what you're doing.
If the various data items are part of a larger, composite data type (such as a mailing address, or a line item in a sales order, or some other type described by multiple attributes), then define a struct type to represent a single value of that composite type:
struct addr { // struct type to represent mailing address
char *name;
int streetNumber;
char *streetName;
char *unitNumber;
char *city;
char state[3];
int ZIP;
};
struct addr getAddressFor(char *name) {...}
struct point2D {
int x;
int y;
};
struct polygon2D {
size_t numPoints;
struct point2D *points;
};
struct point2D getOrigin(struct polygon2D poly) {...}
Do not define a struct to collect random items that aren't somehow related to each other; that's just going to cause confusion for you and anyone who has to maintain your code down the road.
If the data items are not functionally related, but are somehow operationally related (e.g. data plus a status flag plus metadata about the operation or items as part of a single input operation), then use multiple writable parameters. The most obvious examples are the *scanf() functions in the standard library. There are also the strtod() and strtol() functions, which convert a string representation of a number; they return the converted value, but they also write the first character that was not converted to a separate parameter:
char *str = "3.14159";
double value;
char *chk;
value = strtod(str, &chk);
if (!isspace(*chk) && *chk != 0)
printf("Non-numeric character found in %s\n", str);
You can combine these approaches; here's an example inspired by some work I'm currently doing:
typedef enum {SUCCESS, REQ_GARBLED, NO_DATA_OF_TYPE, EMPTY, ERROR} Status;
typedef struct bounds {...} Bounds;
tyepdef struct metadata {
size_t bytesRead;
size_t elementsRead;
size_t rows;
size_t cols;
} Metadata;
typedef struct elevations {
size_t numValues;
short *elevations;
} Elevations;
Elevations elevs;
Metadata meta;
Bounds b = ...; // set up search boundary
Status stat = getElevationsFor(b, &elevs, &meta);
The service that I request elevation data from returns a 1-d sequence of values; the dimensions of the array are returned as part of the metadata.
You can do it using structures:
#include <stdio.h>
struct dont { int x; double y; };
struct dont fred(void)
{
struct dont b;
b.x = 1;
b.y = 91.99919;
return b;
}
int main(int argc, char **argv)
{
struct dont look = fred();
printf("look.x = %d, look.y = %lf\n", look.x, look.y);
return 0;
}
You cannot return multiple values from a C function.
You can either
Return a data structure with multiple values, like a struct or an array.
Pass pointers to the function and modify the values of the pointers inside the function. You need to pass x number of pointers where x is the number of return values you need
To return multiple values from a function we should use a pointer. Here is an example through which you can understand it better
int* twoSum(int* nums, int numsSize, int target) {
int i,j,*a;
a=(int*)malloc(2*sizeof(int));
for(i=0;i<numsSize;i++)
for(j=i+1;j<numsSize;j++)
if(nums[i]+nums[j]==target)
{
a[0]=i;
a[1]=j;
return a;
}
}
I´m a beginner in C, so I don´t have experience with array, pointer, structure. To get more than one value from my function I just used a global variable.
Here is my code:
#include <stdio.h>
double calculateCharges( double hourCharges );
// Global variable for totalCharges-function and main-function interaction
double totalCharges = 0;
int main ( void ) {
double car1 = 0;
double car2 = 0;
double car3 = 0;
double totalHours = 0;
printf( "%s", "Hours parked for Car #1: ");
scanf( "%lf", &car1 );
printf( "%s", "Hours parked for Car #2: ");
scanf( "%lf", &car2 );
printf( "%s", "Hours parked for Car #3: ");
scanf( "%lf", &car3 );
totalHours = car1 + car2 + car3;
printf( "%s", "Car\tHours\tCharge\n");
printf( "#1\t%.1f\t%.2f\n", car1, calculateCharges( car1 ));
printf( "#2\t%.1f\t%.2f\n", car2, calculateCharges( car2 ));
printf( "#3\t%.1f\t%.2f\n", car3, calculateCharges( car3 ));
printf( "TOTAL\t%.1f\t%.2f\n", totalHours, totalCharges);
}
double calculateCharges( double hourCharges ) {
double charges = 0;
if( hourCharges <= 3.0 ) {
charges = 2;
} else if ( hourCharges >= 24.0) {
charges = 10.00;
} else {
charges = ((hourCharges - 3.0)*0.5) + 2.0;
}
totalCharges += charges;
return charges;
}
Method 1 is using array
Method 2 is using pointer
Method 3 is using structure

Resources