Accessing certain elements in an Struct in C - c

So I have the following struct I created:
struct _I_TypeInstructions {
const char *instructionName;
char *opcode;
} I_TypeInstructions[] = { { "lw", "100011" }, { "sw", "101011" }, { "beq",
"000100" } };
typedef struct _I_TypeInstructions I_TypeInstructionsStruct;
If I have a new instructionName and I want to check if it is in the I_TypeInstructionsStruct how do I iterate through just the *instructionName part of the struct above. For example the function I want to write would look something like
bool checkIfInstructionIsI_Type(char *instructionName) {
// somehow iterate through instructionNames in the struct above
// checking if parameter char *instructionName in this method is equal to
// "lw" "sw" "beq" but skipping over the binary numbers.
}

Searching a list of structs is rather straight forward:
bool checkIfInstructionIsI_Type(char *instructionName)
{
for (int i = 0; i<NumInstructions; i++)
{
if (strcmp(I_TypeInstructions[i].instructionName, instructionName) == 0)
{
return true;
}
}
return false;
}

int i;
for(i = 0; i < 3; ++i)
{
if (strcmp(instructions[i].instructionName, instructionName) == 0)
{
printf("Match found");
}
}

It's generally more useful to return the actual element that matches your string. It's the same amount of work anyway.
Add an empty element to the end of your array and then you have a end marker.
typedef struct _I_TypeInstructions {
const char *instructionName;
char *opcode;
} I_TypeInstructionsStruct;
I_TypeInstructionsStruct I_TypeInstructions[] = {
{ "lw", "100011" },
{ "sw", "101011" },
{ "beq", "000100" },
{ 0, 0}
};
I_TypeInstructionsStruct *find_instruction(char *name)
{
I_TypeInstructionsStruct *i ;
for (i = I_TypeInstructions ; i->instructionName ; i++)
if (!strcmp(i->instructionName,name)) return i ;
return 0 ;
}

Related

Pass a 2D array to function

I have a 2D array
byte sensor_AND_1[2][NUM_OF_MAX_SENSORS] = { { 0 }, { 0 } };
byte sensor_AND_2[2][NUM_OF_MAX_SENSORS] = { { 0 }, { 0 } };
and a function where I need to pass the array to
if (is_valid_sensor_id_AND(sensor_AND_1,ID)) { /*do something*/ }
else if (is_valid_sensor_id_AND(sensor_AND_2,ID)) { /*do something*/ }
What is the correct declaration to pass the whole array to the function?
bool is_valid_sensor_id_AND(byte *arr, byte sensor_id)
{
for (size_t i = 0; i < NUM_OF_MAX_SENSORS; i++) {
if (arr[0][i] == sensor_id) {
arr[1][i] = 1;
if (isset_counter(arr[1], NUM_OF_MAX_SENSORS)==isset_counter(arr[0], NUM_OF_MAX_SENSORS)) { triggered(sensor_id); memset(arr[1], 0, NUM_OF_MAX_SENSORS); }
return true;
}
}
return false;
}
I found the answer how to pass it to the function:
bool is_valid_sensor_id_AND(byte arr[][], byte sensor_id)

Iterate through an array defined in other source file

For someone of you maybe a simple question:
How to iterate through an array defined in other c source file.
Here is an example:
Source file producer.c
typedef struct
{
int a;
int b;
}values;
values myvalues[] =
{
{ 2, 5 },
{ 10,15},
{ 20,25},
{ 30,35},
{ 40,45},
};
Source file consumer.c
static void iterateLoop (void)
{
int i;
int x = 5;
for (i = 0; i< (sizeof(myvalues)/sizeof(values)); i++)
{
// Do something with myvalues[i].a;
if (x != myvalues[i].b)
{
// something;
else
{
// something;
}
}
}
This can be done by using callbacks? I need here a 3rd source file which acts as an interface or consumer can access directly the producer?
You can do for example this:
You need a header file values.h
typedef struct
{
int a;
int b;
} values;
Source file producer.c
#include "values.h"
values myvalues[] =
{
{ 2, 5 },
{ 10,15 },
{ 20,25 },
{ 30,35 },
{ 40,45 },
};
int nbofvalues = sizeof(myvalues) / sizeof(myvalues[0]);
Source file consumer.c
#include "values.h"
extern values myvalues[];
extern int nbofvalues;
static void iterateLoop(void)
{
int i;
int x = 5;
for (i = 0; i < nbofvalues; i++)
{
// Do something with myvalues[i].a;
if (x != myvalues[i].b)
{
// something;
}
else
{
// something;
}
}
}

C: Dynamically Allocated Struct Array Usage

Getting errors such as
stats.c:28:36: error: ‘factoryStats’ has no member named ‘candyConsumed’ factoryStatsArray[producer_number].candyConsumed++;
What I want to be able to achieve is to create an array of structs, then access it's members. Is this the wrong way to do it?
Tried using -> but that shouldn't and don't work since I'm storing structs, not pointers to structs.
#include "stats.h"
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int factoryNumber = 0;
int candyProduced = 0;
int candyConsumed = 0;
double minDelay = 0;
double avgDelay = 0;
double maxDelay = 0;
} factoryStats;
factoryStats *factoryStatsArray;
int NUM_FACTORIES = 0;
void stats_init (int num_producers) {
factoryStatsArray = malloc(sizeof(factoryStats) * num_producers);
NUM_FACTORIES = num_producers;
}
void stats_cleanup (void) {
free(factoryStatsArray);
}
void stats_record_produced (int factory_number) {
factoryStatsArray[factory_number].candyProduced++;
}
void stats_record_consumed (int producer_number, double delay_in_ms) {
factoryStatsArray[producer_number].candyConsumed++;
if (factoryStatsArray[producer_number].minDelay == 0) {
factoryStatsArray[producer_number].minDelay = delay_in_ms;
} else {
if (factoryStatsArray[producer_number].minDelay > delay_in_ms) {
factoryStatsArray[producer_number].minDelay = delay_in_ms;
}
}
if (factoryStatsArray[producer_number].maxDelay == 0) {
factoryStatsArray[producer_number].maxDelay = delay_in_ms;
} else {
if (factoryStatsArray[producer_number].maxDelay < delay_in_ms) {
factoryStatsArray[producer_number].maxDelay = delay_in_ms;
}
}
factoryStatsArray[producer_number].avgDelay+= delay_in_ms;
}
void stats_display(void) {
printf("%8s%10s%10s10s10s10s\n", "Factory#", "#Made", "#Eaten", "Min Delay[ms]", "Avg Delay[ms]", "Max Delay[ms]");
for (int i = 0; i < NUM_FACTORIES; i++) {
printf("%8d%8d%8d%10.5f%10.5f%10.5f",
factoryStatsArray[i].factoryNumber, factoryStatsArray[i].candyProduced,
factoryStatsArray[i].candyConsumed, factoryStatsArray[i].minDelay,
factoryStatsArray[i].avgDelay/factoryStatsArray[i].candyConsumed,
factoryStatsArray[i].maxDelay);
}
}
structs cannot be initialized this way. Remove all those = 0 in typedef struct { ... } factoryStats;. Afterwards it compiles as in http://ideone.com/uMgDzE .

how to access first element of a struct array

So I implemented the following method. The problem is that when I begin
searching the variableVector pointer I noticed that variableVector->variables
might not be pointing to the beginning variable element.
Variable* findVariable(VariableVector *variableVector,
char *variableNameOfVariableToReturn) {
if (variableVector->size < 1) {
return NULL ; // since variableVector is empty
}
Variable *currentVariable = variableVector->variables;//<== HOW TO RESET TO BEGINNING???
int numberOfVariablesInVariableVector = variableVector->size;
for (int i = 0; i < numberOfVariablesInVariableVector; i++) {
if (strcmp(currentVariable->variableName,
variableNameOfVariableToReturn) == 0) {
return currentVariable;
} else {
currentVariable++;
}
}
return NULL ; // variable not found in variableVector
}
These are what my structs look like:
struct _Variable {
char *variableName;
char *arrayOfElements;
int32_t address;
};
typedef struct _Variable Variable;
struct _VariableVector {
int size; // elements full in array
int capacity; // total available elements
Variable *variables;
};
typedef struct _VariableVector VariableVector;
Also this is how I add a new variable:
bool appendVariable(VariableVector *variableVector, Variable *variable) {
if (variableVector->size == variableVector->capacity) {
return false;
} else { // append since vector is not full
int indexOfFirstEmptyElement = variableVector->size;
memcpy(&variableVector->variables[indexOfFirstEmptyElement], variable, sizeof(Variable));
//variableVector->variables[indexOfFirstEmptyElement] = *variable;
variableVector->size++;
return true;
}
}

changing size of array

I have the following code:
typedef struct my_data {
char* name;
}my_data;
my_data data[]={
{ .name = "Peter" },
{ .name = "James" },
{ .name = "John" },
{ .name = "Mike" }
};
void loaddata()
{
FILE * in;
if((in = fopen("data.txt","rt")) != NULL) {
memset(data, 0, sizeof(data));
int i = 0;
while(!feof(in))
{
fscanf(in,"%s", &data[i].name);
i++;
};
fclose(in);
}
}
to read contents and process them I use this:
for (i=0; i<sizeof(data)/sizeof(data[0]); i++)
but if the number of lines in file is less than the number of defined array I get a lot of empty records so I modified it into:
for (i=0; (i<sizeof(data)/sizeof(data[0])) && strlen(data[i].name)>0; i++)
which is working fine but I'm sure I will get errors if the number of lines in file will be larger than the defined array size.
Any idea how to make this code safe? To change array dynamically?
EDIT:
this way is working with size 300
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct my_data {
char name[100];
}my_data;
struct my_data data[300];
my_data data_arr[]={
{ .name = "Peter" },
{ .name = "James" },
{ .name = "John" },
{ .name = "Mike" }
};
void process_data()
{
char name[100];
int i;
for (i=0; (i<sizeof(data)/sizeof(data[0])) && strlen(data[i].name)>0; i++) {
sprintf(name, "%s", data[i].name);
printf("%s\n", name);
}
}
void load_data()
{
int i = 0;
FILE * in;
if((in = fopen("data.txt","rt")) != NULL) {
while(!feof(in))
{
fscanf(in,"%s", &data[i].name);
i++;
};
fclose(in);
}
else
{
for (i=0; (i<sizeof(data_arr)/sizeof(data_arr[0])) && strlen(data_arr[i].name)>0; i++) {
sprintf(data[i].name, "%s", data_arr[i].name);
}
}
return;
}
int main()
{
load_data();
process_data();
return 0;
}
Arrays do not grow dynamically in C. So you have a few approaches:
get a pointer to a block of memory (using malloc) and use realloc whenever you need more space for an array - and index into your pointer
create a linked list using malloc for every new item you want to add to your list
Don't forget when using malloc to call free on every single block that you called malloc for.

Resources