enum variable is showing error even after declaring in C - c

I tried to learn enumeration in c and my doubt is the enum variable is showing error even after i have declared it but the same code works fine when i use it via a function?
The code which is showing error:
the variable per1 and per2 are showing error, what is the reason for it?
enum mar_status
{
single = 100, married = 200, divorced = 300, widowed = 400
};
enum mar_status per1, per2;
per1 = single;
per2 = married
The code which is working fine:
#include<stdio.h>
void global();
int main(){
global();
return 0;
}
void global(){
enum mar_status
{
single = 100, married = 200, divorced = 300, widowed = 400
};
enum mar_status per1, per2;
per1 = single;
per2 = married;
printf("The person 1 is %d and person 2 is %d\n",per1,per2);
}
Thanks for the people who helps to solve my query!

C does not allow executable statements outside functions.
The first five lines are declarations and are correct.
The last two lines are executable statements:
per1 = single;
per2 = married;
and must be placed inside a function, e.g. main as in your second piece of code.
You can also do the declaration with an initial value if you want to keep it outside a function:
enum mar_status {
single = 100, married = 200, divorced = 300, widowed = 400 };
enum mar_status per1 = single;
enum mar_status per2 = married;
int main(){
printf("The person 1 is %d and person 2 is %d\n",per1,per2);
return 0;
}

Related

how to associate enum with array of string

If  I have array string for courses name like
courseName = {"java","math","physics"}
and enum have constant variables with code for courses like
CSC = 320
How to associate them in C language ?
You need some way to map the enumeration to the array index.
A simple array of structures with a "from" and "to" member solve it:
struct
{
int course; // Course enumeration value
unsigned name; // Name array index
} course_to_name_map[] = {
{ JAVA_101, 0 },
// etc...
};
To find the name loop over the mapping array to find the course, and then use the corresponding index to get the name:
char *get_course_name(int course)
{
static const size_t map_element_count = sizeof course_to_name_map / sizeof course_to_name_map[0];
for (unsigned i = 0; i < map_element_count; ++i)
{
if (course_to_name_map[i].course == course)
{
return course_names[course_to_name_map[i].name];
}
}
// Course was not found
return NULL;
}
Note that this is only one possible solution. It's simple but not very effective.
why not:
enum KEY {
KEY_JAVA = 320,
KEY_MATH = 123,
KEY_PHYSICS = 17,
};
char *course_to_name[] = {
[KEY_JAVA] = "java",
[KEY_MATH] = "math",
{KEY_PHYSIC] = "physics",
};
// usage:
course_to_name[KEY_JAVA];
It works quite well as long as courses codes are relatively small.

Suggested way to initialize a struct in C

Is there a suggested way on how to initialize a struct in C? For example:
Book romeo = {"Romeo & Juliet", "Shakespeare", 1600};
Book inferno;
inferno.title = "Divine Comedy";
inferno.author = "Dante";
inferno.year = 1400;
Is one way preferred over the other one? I would think for readability the second one is easier, but if there are a ton of fields it might become unwieldy. Additionally, is there any way to specify the variable name in the first method, something like:
Book romeo = {title="...", author="...", year="...");
Additionally, is there any way to specify the variable name in the
first method, something like:
hope below code helps
#include<stdio.h>
typedef struct Book {
char *title;
unsigned int year;
} Book;
int main()
{
Book B1 = { .year = 1999};
Book B2 = {.title= "Jason Bourne", .year = 1999};
printf("B1.year = %d\n", B1.year);
printf("B2.title = %s B2.year = %d\n", B2.title, B2.year);
return 0;
}
Is one way preferred over the other one?
Note: C defines the first as initialization, the 2nd as assignment.
Yes, global object can be initialized, but not assigned with global code.
// Possible
Book romeo = {"Romeo & Juliet", "Shakespeare", 1600};
Book inferno;
// Not possible outside a function.
inferno.title = "Divine Comedy";
inferno.author = "Dante";
inferno.year = 1400;
is there any way to specify the variable name in the first method
Since C99, members can be specified in any order, complete or not.
Book romeo = {. title = "Romeo & Juliet", .author = "Shakespeare", .year = 1600};
Book romeo = {.year = 1600, . title = "Romeo & Juliet", .author = "Shakespeare" };
Book romeo = {. title = "Romeo & Juliet", .author = "Shakespeare" }; // .year takes on value 0
Yes, there's a way but not exactly as you said.
#include <stdio.h>
typedef struct { int k; int l; int a[2]; } T;
typedef struct { int i; T t; } S;
T x = {.l = 43, .k = 42, .a[1] = 19, .a[0] = 18 }; // x initialized to {42, 43, {18, 19} }
int main(void)
{
S l = { 1, // initializes l.i to 1
.t = x, // initializes l.t to {42, 43, {18, 19} }
.t.l = 41, // changes l.t to {42, 41, {18, 19} }
.t.a[1] = 17 // changes l.t to {42, 41, {18, 17} }
};
printf("l.t.k is %d\n", l.t.k); // .t = x sets l.t.k to 42 explicitly
// .t.l = 41 would zero out l.t.k implicitly
}
Moreover, you should visit this once
and please check here before you ask a question.

C How to use struct, union or enum to build a menu?

I want to build a menu show number, food, and the food price like the example below:
Chocolate cake $5
Strawberry cake $4
...
And also need to have a look up function, for example:
If I enter 1, then it will tell me it is Chocolate cake and it is $5.
I have thought of put struct into enum but it cant work
#include<stdlib.h>
#define MAXSIZE 10
struct price{
char name[20];
int price;
};
enum menu{
struct price menu[10];
struct price menu[0] = 1;
struct price menu[1] = 2;
struct price price[2] = 3;
struct price price[3] = 4;
struct price price[4] = 5;
struct price price[5] = 6;
struct price price[6] = 7;
struct price price[7] = 8;
struct price price[8] = 9;
struct price price[9] = 10;
};
int main(void){
struct price menu[0] = {"Cheese Cake", 90};
struct price menu[1] = {"Chocolate Cake", 90};
struct price price[2] = {"Macha Cake", 90};
struct price price[3] = {"Strawberry Cake", 90};
struct price price[4] = {"Pancake", 90};
struct price price[5] = {"Juice", 90}
struct price price[6] = {"Red tea", 90};
struct price price[7] = {"Green tea", 90};
struct price price[8] = {"Bread", 90}
struct price price[9] = {"Flower Tea", 90};
printf("Please enter the number: ");
//scanf("%d", )
}
I think the way I use enum and struct is wrong. And I found out that I can not enter the number to search for the right food and its price if I write code in this way.
Enumeration or enum is a user defined datatype in C language. It is used to assign names to the integral constants which makes a program easy to read and maintain. The keyword “enum” is used to declare an enumeration. so you cant use structs inside enum!
one way to do this is by declaring an array of price structs with the size of the enum ( the menu) and then accessing this array by the enum choise, see below:
typedef enum menu{
Cheese_Cake = 0,
Chocolate_Cake = 1,
....
....
} menu;
struct price menu_arr[MAXSIZE ];
Now initialize the menu_arr (structs array), to be aligned to the enum menu. see below:
strncpy(menu_arr[0].name,"Cheese Cake",19);
menu_arr[0].price = 90;
. . .
/*kepp initializing all the menu array one by one*/
. . .
void chose_from_menu(menu user_choice)
{
printf("your choice is: %s, and the price is: %d !", menu_arr[user_choice].name, menu_arr[user_choice].price)
...
...
/*you can do what ever you like here*/
}
For the menu list, since you are using a hard coded menu, you could do something like the following definitions to create the menu.
I have modified the struct you provided to include a Product Line Number or PLU which is a standard identifier for items in a store. PLUs are assigned to each item in a store and are used on bar codes as well.
typedef struct {
unsigned long ulPlu;
char szMnemonic[30];
long lPrice;
} MenuItem;
MenuItem myMenu[] = {
{11, "Cheese Cake", 90},
{12, "Chocolate Cake", 90},
{13, "Macha Cake", 90},
{21, "Red tea", 90},
{22, "Green tea", 90},
{0, "", 0} // PLU of 0 indicates the end of the menu list
};
Normally an item lookup is done by looking up the PLU in a database. In this case your database is just a small memory resident array of menu items. The key to the data is the unique PLU number which is assigned to each item.
The simplest way to do that is write a function that has as its arguments the PLU number to look up along with the menu list. The function uses a loop to iterate over the array and compare the PLU number the user has entered against the PLU of each of the menu items. Should it find a match, it returns that element. If it doesn't then it returns an error code.
To simplify the logic, I would typically use an extra MenuItem element of the array with a special code that is otherwise unused in order to indicate the end of the array. A PLU number should never be zero (0) so I would use that.
An alternative is to pass in the number of array elements instead of depending on a sentinel value such as zero. The easiest way to do that with an array such as the above where it is all defined with a compiler generated number of elements is to use the sizeof() operator as in sizeof(myMenu)/sizeof(myMenu[0]) which will take the total number of bytes in the array and then divide by the size of each element of the array in order to calculate the number of elements in the array.
Should you use the alternative, you should remove the sentinel value or last array entry, {0, "", 0} of the array definition as it is no longer needed since you are using the number of elements in the array rather than a sentinel value to know how many loop iterations to do before reaching the end of the array.
#include <stdio.h>
typedef struct {
unsigned long ulPlu; // Product Line Unit number, unique to each item
char szMnemonic[30]; // mnemonic for the item
long lPrice; // price for the item with an assummed decimal point.
} MenuItem;
MenuItem myMenu[] = {
{11, "Cheese Cake", 90}, // menu item - PLU number, mnemonic, price
{12, "Chocolate Cake", 90},
{13, "Macha Cake", 90},
{21, "Red tea", 90},
{22, "Green tea", 90},
{0, "", 0} // special sentinal value to indicate end of the array.
};
typedef struct {
int errCode; // error code. 0 if no error.
const MenuItem * item; // pointer to the item found if errCode is zero.
} MenuItemRet;
// Lookup function that expects array to be terminated with an empty menu
// item that has a PLU number of zero.
MenuItemRet LookupPlu(unsigned long ulPlu, const MenuItem * myMenu)
{
MenuItemRet ret = { -1, NULL }; // default is the item not found case
for (size_t i = 0; myMenu[i].ulPlu != 0; i++) {
if (myMenu[i].ulPlu == ulPlu) {
MenuItemRet retFound = { 0, myMenu + i }; // found item. return pointer to item found.
return retFound;
}
}
return ret;
}
// Lookup function that requires the actual number of menu items in the array.
MenuItemRet LookupPlu2(unsigned long ulPlu, const MenuItem * myMenu, size_t nMenuCount)
{
MenuItemRet ret = { -1, NULL }; // default is the item not found case
for (size_t i = 0; i < nMenuCount; i++) {
if (myMenu[i].ulPlu == ulPlu) {
MenuItemRet retFound = { 0, myMenu + i }; // found item. return pointer to item found.
return retFound;
}
}
return ret;
}
int main()
{
MenuItem transactionData[100] = { {0, "", 0} }; // allocate a max transaction size.
unsigned short transactionIndex = 0;
long transactionTotal = 0;
unsigned long ulPlu = 0;
// as long as the user enters menu items we will add them to the transaction data
// until we reach the maximum number of items the transaction data area can hold.
while (transactionIndex < sizeof(transactionData)/sizeof(transactionData[0])) {
MenuItemRet menuItem;
printf ( "Enter PLU for item or 0 to exit\n");
scanf_s("%lu", &ulPlu);
if (ulPlu == 0) break;
#if USE_SENTINAL
// use the lookup function that requires a sentinal value.
if ((menuItem = LookupPlu(ulPlu, myMenu)).errCode >= 0) {
#else
// use the lookup function that requires number of menu items to be known.
// since we know a PLU value of zero is invalid, we do not bother trying to
// remove the last menu item from the array elements count as it will be ignored anyway.
if ((menuItem = LookupPlu2(ulPlu, myMenu, sizeof(myMenu)/sizeof(myMenu[0]))).errCode >= 0) {
#endif
// PLU lookup found this item so print out the item data then
// add the item to the transaction data.
printf("%s at %ld\n", menuItem.item->szMnemonic, menuItem.item->lPrice);
transactionData[transactionIndex++] = *menuItem.item;
}
else {
printf ( "PLU %lu does not exist\n", ulPlu);
}
}
// calculate the transaction total.
transactionTotal = 0;
for (unsigned short i = 0; i < transactionIndex; i++) {
transactionTotal += transactionData[i].lPrice;
}
printf("Transaction total = %ld", transactionTotal);
return 0;
}

can't seem to locate the struct

I am trying to fetch values from a struct once its been updated however the problem am facing is an undeclared error as it cannot seem to see it.
sonicNav.h file
#include<stdio.h>
#include<stdlib.h>
#include"sonicThread.h"
extern void calcSonicS();
sonicThread.c file.
int funcLock = 0;
void calcSonicS() {
struct results *rData = results;
rData = malloc(sizeof(struct results));
int newVal1 = rData->sens1;
int newVal2 = rData->sens2;
int newVal3 = rData->sens3;
int newVal4 = rData->sens4;
if(funcLock == 0){
funcLock = threadFunc();//returns INT value of 1.
}
printf("value 1: %d value 2: %d value 3: %d value 4 %d\n", newVal1, newVal2, newVal3, newVal4);
}
sonicThread.h file
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
#include<string.h>
#include<errno.h>
#include<pthread.h>
#include<sys/time.h>
#include<wiringPi.h>
//GPIO PINS stored within structs, for each sonic range finder.
typedef struct sonicPins{
//pins and id.
int trig;
int echo;
int id;
}args;
typedef struct results{
//all pins
int sens1;
int sens2;
int sens3;
int sens4;
}rData;
sonicThread.c file
void* setup(void *pinsPtr);
extern int threadFunc();
pthread_t pt[4];
int threadFunc()
{
struct sonicPins pinsArray[4] = { { 21, 20, 1 }, { 16, 12, 2 }, { 26, 19, 3 }, { 13, 6, 4 } };
for(int i =0; i <4; i++){
pthread_create(&pt[i], NULL, setup, &pinsArray[i] );
}
return 1;
}
void* setup(void *pinsPtr)
{
struct sonicPins *ptr = pinsPtr;
int trig = 0, Echo = 0, id;
trig = ptr->trig;
Echo = ptr->echo;
id = ptr->id;
struct results *storePtr;
}
The snippet above does update the struct "results", all threads does work concurrently each sensor giving out is own result.
Main.c
int main(){
//void(*foo1)(int, int, int);
//foo1 = &calcSonicS;
printf("In operation\n");
int operational = 1;
while(operational ==1)
{
//sonic range finders.
calcSonicS();
//gyroscope and acceometer.
}
return 0;
}
Error output:
sonicNav.c: In function ‘calcSonicS’:
sonicNav.c:5:28: error: ‘results’ undeclared (first use in this function)
sonicNav.c:5:28: note: each undeclared identifier is reported only once for each function it appears in
struct results *rData = results;
error: ‘results’ undeclared (first use in this function)
The above line tries to declare and define a local variable named rData, which has type struct results *, and initialise it with the value of the variable (local or global) results. The error message is telling you that there is no such variable.
What you're probably mixing up is C++ (old, bad) style initialisation:
MyClass variable = MyClass();
Since the next thing you do with rData is assigning it ...
rData = malloc(sizeof(struct results));
... the solution to your issue is to just remove that "wrong initialisation" from the preceeding line altogether. You could also pack it into a single line:
struct results *rData = malloc(sizeof(struct results));
Looking at ...
typedef struct results{
// ...
} rData;
... I'd guess that you have a serious misunderstanding of the relationship of structure (type) names, type names and variable names. The above definition gives you:
The name results as structure (type) name, so it can be used after struct to name the defined structure type.
The name rData as type name, referring to the same (structure) type as struct results.
When you then declare a variable struct results *rData you have additionally rData as name for a variable. This is possible, but far from good style.
If you remove the typedef, then things would change drastically: You'd then have a global variable named rData of type struct results.

How to print out the members of a struct, weird errors?

I've been trying to print of the members of a struct I have created, however there are a few declarations errors that are showing saying my structs are undeclared. I have a separate function for printing the members of the struct. I have no idea on how to debug it... please help
I have errors such as game1- undeclared (first use in this function) and expected = , ; asm or attribute before { token
#include <stdio.h>
#include <stdlib.h>
struct video_game
{
char *name, *genre, *developer, *platformer, *app_purchase;
int release_year, age_limit;
float price;
};
void print_video_game_details(struct video_game* s)
{
printf("\nTitle: %s\n", s->name);
printf("Genre: %s\n", s->genre);
printf("Developer: %s\n", s->developer);
printf("Year of Release: %d\n", s->release_year);
printf("Lower Age Limit: %d\n", s->age_limit);
printf("Price: $%f\n", s->price);
printf("In-app Purchase: %s\n", s->app_purchase);
}
int main(int agrc, char* agrv[])
{
struct video_game game1
{
game1.name = "Candy Crush Saga";
game1.genre = "Match-Three Puzzle";
game1.developer = "King";
game1.release_year = 2012;
game1.platform = "Android, iOS, Windows Phone";
game1.age_limit = 7;
game1.price = 0.00;
game1.app_purchase = "Yes";
};
struct video_game game2
{
game2.name = "Halo 4";
game2.genre = "First Person Shooter";
game2.developer = "343 Industries";
game2.release_year = 2014;
game2.platform = "Xbox 360, Xbox One";
game2.age_limit = 16;
game2.price = 69.95;
game2.app_purchase = "No";
};
struct video_game game1
{
game3.name = "Uncharted 2: Among Thieves";
game3.genre = "Action adventure RPG";
game3.developer = "Naughty Dog";
game3.release_year = 2012;
game3.platform = "PS3";
game3.age_limit = 16;
game3.price = 30.00;
game3.app_purchase = "No";
};
print_video_game_details(&game1);
print_video_game_details(&game2);
print_video_game_details(&game3);
return 0;
}
Your instance creations (game1, game2 and game3) are not C, they are using some made-up syntax.
They should be something like
struct video_game game1 = {
.name = "Candy Crush Saga",
/* ... */
};
You need to define three variables of type struct video_game, and <type> <name> [= <initializer>] is (roughly) how variables are defined in C.
If you don't have C99, it must be:
struct video_game game1 = {
"Candy Crush Saga",
"Match-Three Puzzle",
"King",
"Android, iOS, Windows Phone",
"Yes",
2012,
7,
0.00
};
Things to notice, that you seem to be ignoring:
No names of fields inside the initializer, just values.
The order must be exactly the same as when the struct was declared; first five strings, then two integers, then a float.
Values are separated with commas, not semicolons.

Resources