I have my own data type since C89 doesn't allow bool type. I can't use C99 sadly.
I have tested the below code and my program is not even recognizing that the names are different. The names are working just fine. I have those loaded in an instance of the struct.
struct ROOM roomList [MAX_ROOMS_COUNT];
I used memset and strcpy to copy in a list of rooms from a room array. Testing this gives me the results I want like so...
printf("%s", roomList[1].name)
printf("%s", roomList[2].name)
...
printf("%s", roomList[7].name)
The rooms array has 7 values.
#define MAX_ROOMS_COUNT 7
typedef enum {
true = 1,
false = 0
} boolean;
struct ROOM {
char name[8];
char* type;
int numConnections;
char* connections [MAX_CONNECTIONS_COUNT];
};
boolean isSameRoom(struct ROOM x, struct ROOM y) {
//printf("Is Same Room, 1:%s, 2:%s\n", x.name, y.name);
if (x.name == y.name) {
//printf("ROOM IS SAME!");
return true;
}
else {
return false;
}
}
struct ROOM getRandomRoom() {
int random = rand() % MAX_ROOMS_COUNT;
return roomList[random];
}
void addRandomConnection() {
struct ROOM A;
struct ROOM B;
A = getRandomRoom();
do {
B = getRandomRoom();
}while(isSameRoom(A, B) == true);
//printf("Add Random Connection, 1:%s, 2:%s\n", A.name, B.name); //for testing purposes
}
Using the print statements I can see that the isSameRoom function isn't working. It's generating random rooms just fine, but there are instances when I run the program that I'm getting the same room for A and B. Any idea why? Thanks! :)
First of all, you're using pass-by-value for these structures, which is pretty inefficient. You should do pass by reference.
Second, as others mentioned, you cannot compare fixed-size strings with == in C; you have to use strncmp or some other structure.
Perhaps a better idea would be to do the whole comparison of the whole structure with memcmp?
return memcmp(&A, &B, sizeof(struct ROOM)) == 0;
Related
My program needs to take people's input and calculate salary and withholds and print all of it out. I have the print outs but I'm having trouble storing it in the array.
#include <stdio.h>
#include <stdlib.h>
typedef char *string;
#define MaxEmployees 100
typedef struct {
string name;
string title;
string ssnum;
double salary;
int withholding;
} employeeRecordT;
typedef struct {
string name;
string title;
string ssnum;
double salary;
int withholding;
} *employeeT;
Type: payrollT
This type represents an entire collection of employees. The type definition uses a dynamic array of employeeT values to ensure that there is no maximum bound imposed by the type. The cost of this design is that the programmer must explicitly allocate the storage for the array using NewArray.
typedef struct {
int nEmployees;
employeeT *employees;
} *payrollT;
Global variables
staff -- Array of employees
nEmployees -- Number of employees
manager -- Used to produce a figure for the code
static employeeT staff[MaxEmployees];
static int nEmployees;
static employeeRecordT manager = {
"Ebenezer Scrooge", "Partner", "271-82-8183", 250.00, 1
};
Private function declarations:
static void InitEmployeeTable(void);
static payrollT CreatePayroll(employeeT staff[], int nEmployees);
static void ListEmployees(payrollT payroll);
static double AverageSalary(payrollT payroll);
static void WeeklyPayroll(payrollT payroll);
//static void GetPayroll(void);
static double ssnum(payrollT payroll);
Main program:
int main(void)
{
payrollT payroll;
//GetPayroll(payroll);
InitEmployeeTable();
payroll = CreatePayroll(staff, nEmployees);
ListEmployees(payroll);
WeeklyPayroll(payroll);
}
static void InitEmployeeTable(void)
{
employeeT empRec;
int condition = 1;
int emp_id = 2;
empRec = (employeeT)malloc(sizeof (employeeT));
empRec->name = "Ebenezer Scrooge";
empRec->title = "Partner";
empRec->ssnum = "271-82-8183";
empRec->salary = 250.00;
empRec->withholding = 1;
staff[0] = empRec;
empRec->name = "Bob Cratchit";
empRec->title = "Clerk";
empRec->ssnum = "314-15-9265";
empRec->salary = 15.00;
empRec->withholding = 7;
staff[1] = empRec;
nEmployees = 2;
do {
//malloc(sizeof ());
char name;
char title;
char ssnum;
float salary;
double withholding;
printf("enter name or input stop to quit!\n");
printf("enter first and last name\n");
scanf("%s", empRec->name);
//empRec->name = name;
printf("\nenter title\n");
scanf("%s", empRec->title);
//empRec->title = title;
printf("\nenter social xxx-xx-xxxx\n");
scanf("%s", empRec->ssnum);
//empRec->ssnum = ssnum;
printf("\nenter salary xx.xx\n");
scanf("%lf", &empRec->salary);
//empRec->salary = salary;
printf("\nenter withhodling x\n");
scanf("%d", &empRec->withholding);
//empRec.withholding = withholding;
printf("printed %d", emp_id++);
staff[emp_id] = empRec;
emp_id++;
if (strcmp(empRec->name,"stop") == 1) {
condition = 0;
break;
}
//staff[emp_id]=empRec;
//emp_id++;
} while (condition = 1);
return 0;
}
You aren't allocating storage for any of your strings (name, title, ssnum [in your records, and now that I looked, in your do-while loop too--you can't use char name;, you need e.g. char name[100]; or pointer with malloc]). Using your typedef for string is somewhat hiding that fact. The only time you can assign to a string variable and have the allocation taken care of for you is at declaration time, since the size is known at compile-time e.g.:
char *str = "Hello";
char *str2 = { 'w', 'o', 'r', 'l', 'd', '\0' };
In your case, the assignment of the strings for manager is fine since they are in the initializer, but you still do need to give explicit sizes for the character arrays in your employeeRecordT.
What you need to do is either give explicit sizes for these character arrays or explicitly allocate storage for them (malloc etc.); and instead of assigning, you must use strcpy() (<string.h>) (or strncpy() in cases where overflow is a possibility).
One thing you could do for something like your title variable to save space is to declare a statically allocated list of strings and then just have title be a pointer to the appropriate element in the list, e.g. (the consts are optional, but just makes sure this array doesn't get messed up in any way):
const char const *titles[] = { "Partner", "Clerk", "etc." };
typedef struct {
const char *title;
// ...
} *employeeT;
// ...
empRec->title = titles[0]; // Points title to "Partner"
You could even use an enum as well to help with the index (all of the rest of the code would be the same):
enum { PARTNER, CLERK, ETC };
// ...
empRec->title = titles[CLERK]; // Points title to "Clerk"
Another issue with your code is that you are only allocating storage for a single employeeT record; you can't reuse empRec without calling malloc() again. What is going to happen is every time you change empRec, it's going to change all of the previous staff elements because they all point to the same location (i.e., staff[0] will contain exactly what you set staff[1] to).
Another issue is that you are taking the sizeof (employeeT) but this is wrong since that is only giving you the size of a pointer to your struct. This is one reason why typedefs can make things more confusing. You should create your struct (and typedef to it if you want), but when you need a pointer to it, you should honestly just use the '*' right there in the code (optionally making a second typedef, i.e. typedef struct { // ... } node; typedef node *node_ptr; or even at the same time: typedef struct { // ... } node, *node_ptr;). You have two options, you can either call malloc() again for empRec before you start assigning its members the second (and subsequent) times, or you can simply discard the empRec variable and use staff directly, e.g.:
staff[0] = malloc(sizeof *staff[0]);
// Note I couldn't use employeeT above since you need struct size, not ptr.
// (`sizeof (employeeRecordT)` could have been used though)
strcpy(staff[0]->name, "Ebenezer Scrooge");
// ...
staff[0]->salary = 250.00;
// ...
Be sure to free() every element in staff[] later on.
Furthermore, I don't see why you have this payrollT type which is essentially a copy of your staff array? If you want payrollT you can just have a pointer to an employee record (which by the way, you probably didn't want employeeT *employees;, you probably wanted either employeeT employees; (since it is already a pointer type) or employeeRecordT *employees). I think this is really the only other thing I see wrong with your program snippet.
If you wanted to, you could get rid of your condition variable, and instead of using a do-while loop, just use a while (1) and your break in your if will exit it for you. This way you can be sure it is still evaluated at least once.
By the way, you don't have to cast the return value of malloc(). It's unnecessary since void pointers are safely and automatically promoted to any other type (and vise versa). See here for more info. Also, I see you mention NewArray but never reference it anywhere.
I'm trying to code a Turing machine in C.
But my program doesn't work, it gets stuck in an endless loop.
Here's my code with some explanations:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3 //number of different states for the cells
#define K 20 //length of the tape
typedef struct
{
int state;
int head;
char tape[];
}mt; //machine
void init_mt(mt* machine, char val[], int n)
{
machine->state=1; //edited mistake
machine->head=0; // edited mistake
int i;
for(i=0;i<n;i++)
{
machine->tape[i]=val[i];
}
}; //initialization of a machine
typedef struct
{
char write;
char direction;
int state;
}actions; //actions composed of three instructions
typedef struct
{
actions exec01;
actions exec02;
actions exec11;
actions exec12;
}program; //program composed of four actions
void execute(actions exec, mt mach)
{
mach.tape[mach.head] = exec.write;
mach.state = exec.state;
if(exec.direction == 'R')
{
mach.head++;
}
else
{
mach.head--;
}
} //class that follows the instructions from the actions
void execute2(mt mach, program p)
{ do{
printf("%c %d %d \n", mach.tape[mach.head], mach.head, mach.state );
if(mach.tape[mach.head] == 0)
{
if(mach.state == 1)
{
execute(p.exec01, mach);
}
else if(mach.state == 2)
{
execute(p.exec02,mach);
}
}
else if(mach.tape[mach.head] == 1)
{
if(mach.state == 1)
{
execute(p.exec11,mach);
}
else if(mach.state == 2)
{
execute(p.exec12,mach);
}
}
}while( (mach.head<K) && (mach.state != 3));
} // class that read the program and act according to the states of the cells,
//keeps going until the machine is at the third state or if it reaches the end of the tape
int main(){
mt machine;
char t[10]={'1','1','1','0','0','1','0','1','0','1'};
init_mt(&machine, t, 10);
program p ={ {'0','R',1}, {'0','R',1}, {'1','R',2}, {'0','L',3} };
execute2(machine, p);
return 0;
} //main with a tape composed of 10 cells and a program composed of four actions
This program keeps displaying "0,0,1" indefinitely and I can't find the error.
Thanks for the help and sorry if this unclear.
There are a few problems here:
In some instances you're passing your structures as arguments, rather than pointers to them. This creates local copies of the entire structures in the called function. Any changes made to those copies will be lost when the functions return. It is also inefficient. Just pass structure pointers.
You aren't declaring any space for tape in your structures, so it's basically a zero-length array. Any kind of access whatsoever will corrupt memory and result in undefined behavior. You have a couple choices here. You can either choose some fixed size for it, and use that for the array size, or you can change it to a pointer and dynamically allocate storage for it. One way or another, you have to allocate the storage.
In execute2, it's comparing mach.tape[mach.head] to the integers 0 and 1. But the tape doesn't contain those values. It contains the characters '0' and '1'. So surround those constants with single quotes. It would also be a good idea to print an error if an unexpected value is encountered. That would have caught this problem instantly.
In function execute, you pass the structure mach by value. In that function you also perform
mach.head++
This, value presumably should be given back to the function execute2. So you will have to pass the structure mach by reference to this function.
I have this datatype I call ItemType which is a string.
typedef <string> ItemType
I am not sure what to put into the "string>" part. I've tried the following:
typedef char[] ItemType and
typedef char* ItemType
neither of them works.
Itemtype is used for an arraylist I am creating in C, indicating what datatype the elements of the Arraylist has. The arraylist itself is generic as it accepts whatever ItemType is and is implemented in a .c file while Itemtype is in the .h header file.
EDIT 1 .c Implementation code snippets:
struct list_type {
ItemType* data;
int size;
int capacity;
};
// adds a component to the array, if enough memory available
void push(ListType listptr, ItemType item) {
if (listptr->size >= listptr->capacity) {
ItemType * temp = malloc(sizeof(ItemType) * (listptr->capacity + 200));
if (temp != NULL) {
listptr->capacity += 200;
memcpy(temp, listptr->data,sizeof(ItemType) * (listptr->size));
free(listptr->data);
listptr->data = temp;
listptr->data[listptr->size] = item;
listptr->size++;
printf("%s inserted:%s ", item, listptr->data[listptr->size]);
}
}
else {
listptr->data[listptr->size] = item;
listptr->size++;
printf("%s inserted:%s ", item, listptr->data[listptr->size]);
}
}
void printl(ListType listptr) {
int i;
for(i = 0; i < listptr->size; i++) printf("%s ", listptr->data[i]);
printf("\n");
}
EDIT .h header file snippets
typedef struct list_type *ListType;
typedef char* ItemType;
//other code
void push(ListType l, ItemType item);
It depends on what you mean by "string".
If you mean an array of char that can be passed to functions like strcpy(), it is easy
typedef char ItemType[10];
declares ItemType to be an array of char, which can hold any C-style string for which strlen() returns 9 or less (the difference of 1 is due to the terminating '\0' terminator that string related functions (strcmp(), strcat(), strlen()) look for to mark the end of the string).
The limitation is that the size is fixed. Write 20 characters to an ItemType (e.g. using strcpy()) and behaviour is undefined. It is your responsibility to ensure too many characters are not written to an ItemType.
If you mean some type that can hold an arbitrary length string, where YOUR code has to manage things to ensure the data storage is large enough, you can do things like
typedef char *ItemType;
The problem with this is that your code needs to manage the memory that pointer points at. ItemType is a pointer, not an array which can hold data.
#include <stdlib.h> /* declares malloc(), realloc(), free(), etc */
/* and in a function somewhere */
ItemType x = malloc(25);
/* can use any operations that do not copy more than 24 characters to x */
/* but if we want a larger string, we have to manage it */
ItemType temp = realloc(x, 50);
if (temp == NULL) /* reallocation failed */
{
/* work out how to recover or terminate */
}
else
{
x = temp;
}
/* If reallocation failed and no recovery is done, do not execute the following code */
/* can now treat x as an array of 50 characters (i.e. if we ensure strlen(x) never exceeds 49 */
free(x); /* when we are done with x */
If you want a string type that will resize itself as needed (e.g. as provided by some other languages) then there is no way in C.
typedef char* ItemType
actually means ItemType = char*.
So basically you have created just another name for char*. ItemType itself is not a variable but a data type. Following is the usage of typedef
int main()
{
typedef char* itemType;
itemType str = (char*) malloc(50);
strcpy(str, "Hello World");
printf("%s\n", str);
return 0;
}
I am having a bunch of problems with pointers and dynamic arrays here.
I have a function that I call, that does a bunch a stuff, like removing an ellement from the dynamic array , which leads me to reallocating memory to one of those dynamic arrays. The problem is I call functions within functions, and I can't return all my values properly to the Main.
Since I can't return 2 values, how can I do this?
structure1* register(structure1 *registerArray,structure2 *waitingList, int counter){
//Bunch of code in here
registerArray = realloc(inspecao, (counter)+1);
waitingList = eliminate(waitingList, 5, counter); //Doesn't matter what it does really
return registerArray;
}
structure1* eliminate(structure1 *arrayToEliminateFrom, int positionToEliminate, int *counter){
//The code for this doesn't matter
//All I do is eliminate an ellement and reallocate it
arrayToEliminateFrom = realloc(arrayToEliminateFrom, (*counter-1)*sizeof(structure1))
return arrayToEliminateFrom;
}
As you can see , I don't know how to return the pointer to the waitingList dynamic array to the Main. How can I do this?
I have searched everywhere.
Help
Okay, here are two ways to do it.
The first is, based upon your comment, what you think your instructor would want:
void
xregister(structure1 **registerArray, int *arrayCount,
structure1 **waitingList, int *waitCount)
{
// Bunch of code in here
*arrayCount += 1;
*registerArray = realloc(inspecao, *arrayCount * sizeof(structure1));
// Doesn't matter what it does really
eliminate(waitingList, 5, waitCount)
}
void
eliminate(structure1 **arrayToEliminateFrom, int positionToEliminate,
int *count)
{
// The code for this doesn't matter
*count -= 1;
// All I do is eliminate an ellement and reallocate it
*arrayToEliminateFrom = realloc(*arrayToEliminateFrom,
*count * sizeof(structure1))
}
Here is what Roberto and I were suggesting. Actually, mine's a general variable length array approach that can be fully generalized with some slight field changes. In a way, since you're already using a struct, I can't see why your instructor would object to this as it's a standard way to do it. Less cumbersome and cleaner.
struct vector {
int vec_count;
structure1 *vec_base;
};
void
xregister(vector *registerArray,vector *waitingList)
{
// Bunch of code in here
registerArray->vec_count += 1;
registerArray->vec_base = realloc(registerArray->vec_base,
registerArray->vec_count * sizeof(structure1));
// Doesn't matter what it does really
eliminate(waitingList, 5)
}
void
eliminate(vector *arrayToEliminateFrom, int positionToEliminate)
{
// The code for this doesn't matter
arrayToEliminateFrom->vec_count -= 1;
// All I do is eliminate an ellement and reallocate it
arrayToEliminateFrom->vec_base = realloc(arrayToEliminateFrom->vec_base,
arrayToEliminateFrom->vec_count * sizeof(structure1))
}
Here's an even more compact way:
struct vector {
int vec_count;
structure1 *vec_base;
};
void
vecgrow(vector *vec,int inc)
{
vec->vec_count += inc;
vec->vec_base = realloc(vec->vec_base,vec->vec_count * sizeof(structure1));
}
void
xregister(vector *registerArray,vector *waitingList)
{
// Bunch of code in here
vecgrow(registerArray,1);
// Doesn't matter what it does really
eliminate(waitingList, 5)
}
void
eliminate(vector *arrayToEliminateFrom, int positionToEliminate)
{
// The code for this doesn't matter
vecgrow(arrayToEliminateFrom,-1);
}
you should try to do an higher structure that contains both pointers and pass and return that structure beetween your functions, because function can return only one object/structure, but your structure/object can contain more objects/structures
If I have a set of small string values, and I want to fetch a numeric value to represent them, what's the best way to do this via a lookup table?
If I were only needing to do a straight look up, I know the optimal solution would just be a series of if statements:
if (strcmp(str, "foo") == 0)
tmp = FOO;
else if (strcmp(str, "bar") == 0)
tmp = BAR;
But, I ask this because these small string values represent an attribute in a small project I'm writing in C, and the attributes can be read-only or read-write (no write-only for now, maybe never).
So what I currently do just to make sure things work is have a lookup function comprised of an if-then clause like above to look up which values are read-only, and a second functions that looks up which values are read-write. But this is large and ugly to me.
I'm thinking, have three functions instead. One function is the lookup function, and it returns an int value that is the numeric form of the string. But this lookup function can also take a flag that determines whether it fetches a read-only value, or a read-write value. If a write operation is done on a value that is really read-only, the function will return -EINVAL (or something equivalent).
The other two functions, now still the read and write, just call this lookup function, passing in a string of the value, and the flag that determines whether they're for reading or writing.
Thing is, I don't know how this is modeled in C (if it can be modeled), and searching Google is tiresome with all the content farms ripping this place off (and giving me C++/C# answers instead).
So this is how I think it'll look:
int lookup_func(const char *name, const char *flag) {
int tmpval = 0;
/* code to do the lookup. */
if (tmpval == 0)
return -EINVAL;
else
return tmpval;
}
int get_readonly_bit(const char *name) {
return lookup_func(name, "ro");
}
int get_readwrite_bit(const char *name) {
return lookup_func(name, "rw")
}
Thoughts? The idea is to reduce code size by not repeating the if-then branches for these two functions, which differ slightly in overall design, and simply let some kind of a lookup function figure out what function this value serves.
Do you not consider just putting a table in? A hash table is also fine if there are lots of properties.
int lookup(const char *name)
{
typedef struct item_t { const char *name; int writable; int value; } item_t;
item_t table[] = {
{ "foo", 0, FOO },
{ "bar", 1, BAR },
{ NULL, 0, 0 }
};
for (item_t *p = table; p->name != NULL; ++p) {
if (strcmp(p->name, prop_name) == 0) {
return p->value;
}
}
return -EINVAL;
}