Enum. Can't find what's wrong - c

In a header file:
typedef struct apartment_t* Apartment;
typedef enum { EMPTY, WALL } SquareType;
struct apartment_t {
SquareType** squares;
int width;
int length;
int price;
};
in the source file:
int apartmentTotalArea(Apartment apartment) {
int countEmpty = 0;
for (int i=0;i<apartment->length;i++)
for (int j=0;j<apartment->width;j++) {
SquareType Square = apartment->squares[i][j];
switch(Square) {
case Square.EMPTY: // Bad
countEmpty++;
break;
case Square.WALL: // Bad
break;
}
}
This function counts the empty spots in a given 2d array. I'm facing a problem in the switch, it'll mark both cases as bad statements. What's wrong with my code? Thank you.

There is no such thing as Square.EMPTY or Square.WALL in your code. Use:
switch(Square) {
case EMPTY: // Juse EMPTY, not Square.EMPTY
countEmpty++;
break;
case WALL:
break;
}

Related

How do I add a "case" to a switch statement programically in C?

If I have a switch statement like this one:
switch(x)
{
case 1:
printf("Hello, world!");
case 2:
printf("Hello!");
}
How can I programically place new case statements inside the switch statements?
This is an example of what I want:
switch(x)
{
case 1:
printf("Hello, world!");
case 2:
printf("Hello!");
}
AddCaseStatementToSwitchStatement("case 3: printf(\"Hi!\")");
You need a lookup table
struct err_def {
int code;
char* message;
};
int main() {
struct err_def errs[] = {
{1,"Hello, world!"},
{2,"Hello"}
};
int sz = 2;
int errorCode = 2;
char* msg;
for (int i = 0; i < sz; i++) {
if (errs[i].code == errorCode) {
msg = errs[i].message;
break;
}
}
}
this one is static but you can do the same thing with a dynamically growing table
If the table gets big you can search it more efficiently by keeping it sorted and doing a binary chop on it

Losing struct values after assigning 'next' and 'prev' struct pointers

I am creating a Book Management system in which the user can search by the title or the author of the book. The problem I am running into is when I try to get the values from the books. When searching for the author, all I get are symbols and an infinite for loop, instead of any of the authors that are already saved in config.
I am more than certain that it is something wrong with the way I am storing these values, but am not sure.
main.c:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char * argv[]) {
struct Books books;
// Config works fine and dandy, don't need to worry about this
cfg = read_config(cfg, "test-cfg.cfg");
for (int size = 0; size < cfg.valuesSize; size++) {
// Gets values from the config and assigns the values to the struct Books
books.id = atoi(cfg.values[size][0][1]);
strcpy(books.name, cfg.values[size][1][1]);
strcpy(books.author, cfg.values[size][2][1]);
strcpy(books.description, cfg.values[size][3][1]);
// Assign prev and next in Books struct
struct Books nextBook;
books.next = &nextBook;
nextBook.prev = &books;
books = *books.next;
}
// This throws Frontend screens at the user
// While also pipelining to backend functions
while(true) {
int welcome = 1;
switch (welcome) {
case 1: {
struct Books booksFound[cfg.valuesSize];
int booksFoundPtr = 0;
int searchOption = 2;
getchar();
if (searchOption==2) {
printf("Enter the Author: ");
char bookAuthor[AUTHOR_MAX];
fgets(bookAuthor, AUTHOR_MAX, stdin);
// Here is where the code screws up.
// It gives me random symbols instead of the book author's name
for (; books.id >= 1; books = *books.prev) {
if (strncmp(books.author, bookAuthor, strlen(books.author))==0) {
booksFound[booksFoundPtr] = books;
booksFoundPtr++;
}
}
}
// Used for showing all matching book authors
for (int i = 0; i < booksFoundPtr; i++) {
printf("ID:%d\nTITLE:%s\nAUTHOR:%s\nDESCRIPTION:%s\n", booksFound[i].id, booksFound[i].name, booksFound[i].author, booksFound[i].description);
char option[2] = {'\0'};
fgets(option, 2, stdin);
switch(atoi(option)) {
case 1: {
if (i+1 == booksFoundPtr) {
i--;
}
break;
}
case 2: {
if (i-1 < 0) {
i--;
break;
}
else {
i-=2;
}
break;
}
default: {
break;
}
}
}
// Rewinds books for next use
while(books.id != cfg.valuesSize) {
books = *books.next;
}
continue;
}
default: {
continue;
}
}
break;
}
return 0;
}
books.h
#define NAME_MAX 60
#define AUTHOR_MAX 100
#define DESCRIPTION_MAX 240
struct Books {
int id;
char name[NAME_MAX];
char author[AUTHOR_MAX];
char description[DESCRIPTION_MAX];
struct Books * next;
struct Books * prev;
};

Call c functions from fortran(type enum)

Recently,I call c function from fortran with iso_c_binding.But I found some c code.such as:
typedef enum
{
STRUMPACK_FLOAT,
STRUMPACK_DOUBLE,
STRUMPACK_FLOATCOMPLEX
} STRUMPACK_PRECISION;
typedef enum
{
STRUMPACK_MT,
STRUMPACK_MPI_DIST
} STRUMPACK_INTERFACE;
typedef struct
{
int solver;
STRUMPACK_PRECISION precision1;
STRUMPACK_INTERFACE interface1;
}STRUMPACK_SparseSolver;
int STRUMPACK_init(STRUMPACK_SparseSolver * S,
STRUMPACK_PRECISION precision1, STRUMPACK_INTERFACE interface1, int verbose)
{
S->precision1 = precision1;
S->interface1 = interface1;
switch (interface1)
{
case STRUMPACK_MT:
{
switch (precision1)
{
case STRUMPACK_FLOAT:
printf("srtumpack_float %d\n", verbose);
break;
case STRUMPACK_DOUBLE:
printf("srtumpack_double %d\n", verbose);
break;
default:
printf("ERROR: wrong precision!");
}
}
break;
default:
printf("ERROR: wrong interface!");
}
return 0;
}
I don't know that call this c subfunction with Fortran.because of this structs:
typedef enum
{
STRUMPACK_MT,
STRUMPACK_MPI_DIST
} STRUMPACK_INTERFACE;
I don't know how to solve this problem . I will appreciate any contribution, suggestion about the problem.
Thanks
That isn't a structure, but an enum (enumeration) supported by ISO binding entity ENUM.
In case your binding miss enumerations the following is a workaround.
Enums in C are more or less constant integers which values are assigned by compiler in generally increasing way. You can also force values for each enum member using assignment as in:
typedef enum
{
STRUMPACK_FLOAT = 0,
STRUMPACK_DOUBLE,
STRUMPACK_FLOATCOMPLEX = 100
} STRUMPACK_PRECISION
In this case i.e. we impose to STRUMPACK_FLOATCOMPLEX the value 100. We made the same with the first member, in any case the first member have value 0 by default. The second member STRUMPACK_DOUBLE will get the value 1 as progressive increment from previous member.
Anyway you can get better info on how enum works googling on the net.
In your case the easier way to solve the problem is to convert enums in definitions and using int's as type like in:
#define STRUMPACK_FLOAT 0
#define STRUMPACK_DOUBLE 1
#define STRUMPACK_FLOATCOMPLEX 2
typedef int STRUMPACK_PRECISION;
#define STRUMPACK_MT 0
#define STRUMPACK_MPI_DIST 1
typedef int STRUMPACK_INTERFACE;
typedef struct
{
int solver;
STRUMPACK_PRECISION precision1;
STRUMPACK_INTERFACE interface1;
} STRUMPACK_SparseSolver;
int STRUMPACK_init(STRUMPACK_SparseSolver * S, STRUMPACK_PRECISION precision1,
STRUMPACK_INTERFACE interface1, int verbose)
{
S->precision1 = precision1;
S->interface1 = interface1;
switch (interface1)
{
case STRUMPACK_MT:
{
switch (precision1)
{
case STRUMPACK_FLOAT:
printf("srtumpack_float %d\n", verbose);
break;
case STRUMPACK_DOUBLE:
printf("srtumpack_double %d\n", verbose);
break;
default:
printf("ERROR: wrong precision!");
}
}
break;
default:
printf("ERROR: wrong interface!");
}
return 0;
}

pointers with structs in structs c

I have tried to create a CD struct like :
typedef struct
{
char* nameCD;
int yearOfpublication;
song* listOfSongs;
int priceCD;
int numberOfSongs;
} CD;
and I have a song struct :
typedef struct
{
char* nameSong;
char* nameSinger;
int lenghtOfSong;
} song;
void SongInput(song *psong, CD *pcd)
{
pcd->numberOfSongs++;
pcd->listOfSongs = (song*)malloc(pmcd->numberOfSongs*sizeof(song));
// here all the code that update one song..
but what should I write to update the next song?
how do I change it into an array which update the number of the songs and how can I save all the songs?
I tried this :
printf("Enter lenght Of Song:");
scanf("%d", &psong->lenghtOfSong);
but I don't understand the pointers..
and how to update the next song?
}
void CDInput(CD *pcd)
{
int numberOfSongs = 0;
//here all the other update of cd.
//songs!!!!!!!!!!!!!!!!!!!!!!!!!!!!
pcd->numberOfSongs = 0;
pcd->listOfSongs = (song*)malloc(numberOfSongs*sizeof(song));
}
Do I need to write anything else?
void CDInput(CD *pcd)
{
int i;
//...
printf("Enter number Of Song:");
scanf("%d", &pcd->numberOfSongs);
pcd->listOfSongs = (song*)malloc(pcd->numberOfSongs*sizeof(song));
for(i = 0; i < pcd->numberOfSongs; ++i){
SongInput(&pcd->listOfSongs[i]);
}
//...
}
It depends on if you want to write the structure once completely or you really want to add one item.
For the first case, please refer to BLUEPIXY's answer, for the second one, thigs are slightly more complicated.
bool add_song(song *psong, CD *pcd)
{
song* newone = realloc(pcd->listOfSongs, (pmcd->numberOfSongs+1)*sizeof(song));
if (!newone) {
// return and complain; the old remains intact.
return false; // indicating failure.
}
// now we can assign back.
pcd->listOfSongs = newone;
newone[pcd->numberOfSongs++] = *psong;
return true; // indicating success.
}

assigning struct in switch not working

In my program, I'm trying to create a new struct based od switch statement, but when I do so, the compiler returns an error:
Syntax error before '{' token on the row with the position assignment
I'm using dev-c++ 4.9.9.2 as an IDE (i think it's using MinGW as compiler). IT's for my brother's programming assignment I'm helping him with, I haven't seen C in a few years, so I'm rusty (and I wasn't a champion before either).
Here's simplified code:
typedef enum{TOP_RIGHT = 0,TOP_LEFT,BOTTOM_RIGHT,BOTTOM_LEFT} diagonal_t;
typedef struct
{
int row;
int column;
} position_t;
...
void checkDiagonal(diagonal_t diagonal_to_check)
{
...
position_t position;
switch(diagonal_to_check)
{
case TOP_RIGHT:
position = {0,0}; //here's the error, but I don't know how to repair it.
//how to create a new struct here without disrupting the
//switch?
break;
case TOP_LEFT:
position = {0,0};
break;
....
}
}
The var_of_type_struct = { init_value } syntax works only in definitions; it does not work in assignments.
Three common ways to deal with is are
Defining a function that initializes your struct
Defining a function that sets fields to parameters that you pass, and
Assigning the individual fields of your struct.
Approach 1:
void init_pos(position_t *p) {
p->row = 0;
p->column = 0;
}
...
case TOP_LEFT:
init_pos(&position);
break;
Approach 2:
void set_pos(position_t *p, int r, int c) {
p->row = r;
p->column = c;
}
...
case TOP_LEFT:
set_pos(&position, 0, 0);
break;
Approach 3:
case TOP_LEFT:
position.row = 0;
position.column = 0;
break;
You can't do that: assignment and initialization are not the same thing. You are attempting to use initializer syntax in an assignment. You'll have to set both fields manually:
case TOP_RIGHT:
position.row = 0;
position.column = 0;
/* ... */
You need to cast to struct type, like this:
position = (position_t){0, 0};

Resources