C++: how get an access to data stored in the multimap static variable - static

I write a class with a structure and with some methods which will work with multimap. The addItemToList-method will add a structure in multimap and saveListData-method will store it on a binary file:
class listData
{
public:
struct ItemStruct
{
long int item_id;
int ess_id;
char item_type;
char list_type;
time_t add_date;
};
int addItemToList(long int item_id, char list_type, char item_type = '\0', int ess_id = 0)
{
ItemStruct *pAddingItem = new ItemStruct;
pAddingItem->item_id = item_id;
pAddingItem->list_type = list_type;
pAddingItem->item_type = item_type;
pAddingItem->ess_id = ess_id;
pAddingItem->add_date = std::time(nullptr);
typedef std::multimap<char, struct ItemStruct> ListDataMap;
static ListDataMap container;
container.insert(std::pair<char, struct ItemStruct>(list_type, *pAddingItem));
return 0;
}
int saveListData()
{
// how can I access to data stored in the container static variable?
return 0;
}
};
and the next code for use the class:
#include <ctime>
#include <iostream>
#include <map>
#include "lists.cpp"
using namespace std;
int main(int argc, char** argv)
{
listData test;
test.addItemToList(10, 's', 'm', 1555);
test.addItemToList(10, 'c', 'm', 1558);
test.saveListData();
}
How can I access to data stored in the container static variable?

In your code, you have declared your multimap at the local scope of the method addItemToList, not at class scope. When you want to access it in various methods of your class, you have to declare and define it at class scope.
Additionally, I've adjusted the content of your addItemToList implementation to avoid a memory leak.
For simplicity, I put everything in a single file:
#include <ctime>
#include <iostream>
#include <map>
using namespace std;
class listData
{
private:
struct ItemStruct
{
long int item_id;
int ess_id;
char item_type;
char list_type;
time_t add_date;
};
typedef std::multimap<char, struct ItemStruct> ListDataMap;
static ListDataMap container; // multimap declaration
public:
int addItemToList(long int item_id, char list_type, char item_type = '\0', int ess_id = 0)
{
ItemStruct pAddingItem;
pAddingItem.item_id = item_id;
pAddingItem.list_type = list_type;
pAddingItem.item_type = item_type;
pAddingItem.ess_id = ess_id;
pAddingItem.add_date = std::time(nullptr);
container.insert(std::pair<char, struct ItemStruct>(list_type, pAddingItem));
return 0;
}
int saveListData()
{
// use container here
// container.<whatever-method>
return 0;
}
};
listData::ListDataMap listData::container; // multimap definition
int main(int argc, char** argv)
{
listData test;
test.addItemToList(10, 's', 'm', 1555);
test.addItemToList(10, 'c', 'm', 1558);
test.saveListData();
}

Related

Include variables in seperate file in C?

I created a structure item:
typedef struct item
{
char name[20];
char desc[100];
int lp;
int shield;
int weapon;
} item;
I need 36 of them so I create an array item treasure[6][6];
For each item I insert the data as so:
strcpy(treasure[0][0].name, "name");
strcpy(treasure[0][0].desc, "none");
treasure[0][0].lp = 0;
treasure[0][0].shield = 0;
treasure[0][0].weapon = 200;
I do this 36 times and takes a lot of space in editor, my question: Can I put this in a separate .c/.h file maybe? I've been trying to but can't make it work.
Thanks for any help!
I suggest that use a file, like init.h with the following content
#include <string.h>
typedef struct item {
char name[20];
char desc[100];
int lp;
int shield;
int weapon;
} item;
item treasure[1][1] = {
{{.name = "name", .desc = "none", .lp = 0, .shield = 0, .weapon = 200}}};
In that way you must be able to initialize the struct of you matrix 6, 6 in another file, then you must be able to access it from the main program calling it like this:
#include "init.h"
#include <stdio.h>
int main() {
printf("%s\n", treasure[0][0].name);
return 0;
}
I hope this work for you, there a another ways to initialize structs, but this one is what I use more often. You can find more information here
https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
If you want to learn how to do proper C program design from the start, then this is how.
The correct way to do this is to create an item.h and a item.c file. Together they form a "code module" (or class, if you will).
Your header file item.h should contain the typedef and header guards. You should write an initialization function too.
// item.h
#ifndef ITEM_H
#define ITEM_H
#include <string.h>
typedef struct {
char name[20];
char desc[100];
int lp;
int shield;
int weapon;
} item_t;
void item_init (item_t* item,
const char name[20],
const char desc[100],
int lp,
int shield,
int weapon);
#endif
You can then implement the init function in init.c:
// item.c
#include "item.h"
void item_init (item_t* item,
const char name[20],
const char desc[100],
int lp,
int shield,
int weapon)
{
strcpy(item->name, name);
strcpy(item->desc, desc);
item->lp = lp;
item->shield = shield;
item->weapon = weapon;
}
These two files, init.h and init.c are only concerned about the behavior of all item_t variables. You can expand them with more functions as you go. They do not and should not contain any actual data.
Now if you want to keep the data separate, you could create a separate pair of files for it like this:
// item_data.h
#include "item.h"
#define ITEMS_N 36
item_t* item_data_get (int item_n);
This is just a "getter" function that lets you access the data. The actual data is encapsulated in the .c file:
// item_data.c
#include "item_data.h"
static item_t items [ITEM_N] =
{
[0] = {.name="name", .desc="none", .lp=0, .shield=0, .weapon=200},
[1] = ... // fill up data here
};
item_t* item_data_get (int item_n)
{
return items[n];
}
If you later on want to change the data of a given item, you can do so by calling item_init(item_data_get(n), ...);

How to allocate a dynamic array of struct

i have a problem with the allocation of a dynamic struct array.
The struct is composed of a char* field, that is another dynamic array of char. After i allocate all arrays, windows block the program when i try to modifty a struct content. Code:
typedef struct
{
char *cod;
}code;
void create_cod(code *singleCode,int codeLength);
void create_codes(code *codes, int codesNumber, int codeLength);
int main()
{
int codesNumber=4, codeLength=10;
code *codes;
create_codes(codes, codesNumber, codeLength);
codes->cod = "abcd"; /*Windows block the program here*/
}
void create_cod(code *singleCode,int codeLength)
{
singleCode->cod = (char*)malloc(codeLength*sizeof(char));
return;
}
void create_codes(code *codes, int codesNumber, int codeLength)
{
codes= (code*)malloc(codesNumber*sizeof(code));
int i=0;
while(i<codesNumber)
{
create_cod(codes+i,codeLength);
i++;
}
return;
}

Swift access to C Struct

I am developing a OS X Swift app for parsing cvs files. It runs successfully in Objective-C. Then I changed to Swift and for performance improvements I developed the parse/import engine in C. It is 5 times faster as in Swift or Objective-C - nice. But I have trouble to exchange the data between C and Swift - especially with Struct:
BridgingHeader:
#include "ToolBoxC.h"
ToolBoxC.h:
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);
typedef struct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
} FileStruct;
typedef struct {
FileStruct fileContent[10000];
} FilesStruct;
struct FilesStruct filesContent;
ToolBoxC.c:
struct FileStruct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
};
struct FilesStruct {
struct FileStruct fileContent[10000];
};
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {
// some stuff
struct FileStruct fileContent;
fileContent.headerArray = headerArray;
fileContent.numberHeaderRows = numberHeaderRows;
fileContent.dateArray = dateArray;
fileContent.numberDateRows = numberDateRows;
fileContent.valueArray = valueArray;
fileContent.stringArray = stringArray;
fileContent.numberValueRows = numberValueRows;
fileContent.numberValueColums = numberValueColumns;
filesContent.fileContent[numberFiles] = fileContent;
return;
}
All the parsed data are stored in struct FilesStruct filesContent. The parsing is started by calling the function loadFile() with parameters from Swift. That works fine. Also the parsing is OK. But how can I access to the data in struct FilesStruct filesContent from Swift?
Thanks, Matthias.
Try this:
ToolBoxC.h
#include <stdbool.h>
struct FileStruct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
};
extern struct FileStruct **loadedFiles;
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);
ToolBoxC.c
#include <stdlib.h>
#include "ToolBoxC.h"
#define MaxFiles 10000
struct FileStruct **loadedFiles;
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {
static int nextIndex = 0;
if (loadedFiles == 0)
loadedFiles = malloc(MaxFiles * sizeof(*loadedFiles));
struct FileStruct *file = malloc(sizeof(struct FileStruct));
file->numberDateRows = xRow;
loadedFiles[nextIndex++] = file;
}
Swift Test Method
func loadFilesTest() -> Void {
for var i:Int32 = 0; i < 10; ++i {
loadFile("", "", "", 0, 0, 0, i, 0, true)
}
for var j = 0; j < 10; ++j {
let pointer = UnsafePointer<FileStruct>(loadedFiles[j])
print("Number of date rows = \(pointer.memory.numberDateRows)")
}
}

Error in Static Global Variable (C)

I have around 14 void functions that contains processes needed in order for my program to work
and all the 14 functions share the same variables so I thought of making them into static Global.
After putting <stdio.h> and all the other headers needed, I have 2 typedef struct and after that, I have put 11 static int variables and 3 static struct variables.
I have checked every single function if the struct variables have been storing the data properly, and apparently, only the void function that is first called in int main() stores the correct data into the struct variable.
When the 2nd void function is called, the global variables from the 1st void function contains no data at all.
Can anyone tell me if using the global variables for multiple functions to work is wrong?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
typedef struct hero_data{
//... data
}hero;
typedef struct item_data{
//.... data
}item;
int totalwarrior = 0;
int totalitem = 0;
int toughtotal = 0;
int nimbletotal = 0;
int smarttotal = 0;
int skeptictotal[3] = {0};
int mystictotal[3] = {0};
int cursedtotal[3] = {0};
int brutetotal[3] = {0};
int shreddertotal[3] = {0};
int vanillatotal[3] = {0};
int typetotal = 0;
int typenum = 0;
int typechoice = 0;
int classchoice = 0;
static item curr3[10000];
static hero curr[10000];
static hero curr2[10000];
static hero smart[1][10000];
static hero nimble[1][10000];
static hero tough[1][10000];
static hero type[3][10000];
static hero skeptic[3][10000];
static hero mystic[3][10000];
static hero cursed[3][10000];
static hero brute[3][10000];
static hero shredder[3][10000];
static hero vanilla[3][10000];
static hero player1;
static hero player2;
int randbetween(int max, int min)
{
//... functioning
}
void mygets(char *name, int len, FILE * stream)
{
//... functioning
}
void available_hero(hero Class[3][10000],int typenum, int classtotal[],int classcode) //Shows the available hero based on Player's choice
{
//... functioning
}
void detail_hero(hero curr[3][10000],int classtotal[],int typenum)
{
//....functioning
}
void detail_item(item curr[10000],int whatitem)
{
//functioning
}
void pointer_conversion(hero *a, hero curr[10000], int total)
{
//....functioning
}
void TDpointer_conversion(hero *a, hero curr[3][10000], int total,int typenum)
{
//....functioning
}
void pointer_conversion2(item *a, item curr3[], int total)
{
//...functioning
}
void OD_conversion(int a[], int curr[],int typenum)
{
//....functioning
}
void TD_conversion(hero a[3][10000],hero curr[3][10000],int typetotal, int typenum, int typetotal2)
{
//....functioning
}
void TD_conversion2(hero a[3][10000],hero curr[3][10000],int typetotal[], int typenum, int typetotal2[])
{
//....functioning
}
void TD_conversion_class(hero a[1][10000],hero curr[3][10000],int classtotal[3], int typenum, int typetotal)
{
//....functioning
}
void binarycheck(int encoding, hero *dummy, int totalwarrior)
{
//....functioning
}
void check_compare_item(hero player)
{
//....functioning
}
void create_player(hero player)
{
//....functioning
}
void load_hero(hero curr[])
{
//....functioning
}
int main()
{
load_hero(curr);
load_item(curr3);
create_player(player1);
printf(""\n --> %s <---\n",player1.name); //struct hero contains the variable "name"
// Nothing gets printed while when I try to print the name within Create_player function, it works.
check_compare_item(player1);
}
When you pass a parameter by-value and changes you make to it inside the called function will not be visible in the caller (the callee is operating on a copy of the data).
Solution: send your data via pointers.
Even better: avoid static variables altogether. What benefit do they offer in this case that a regular variable does not?
If you use a global variable, why do you need to pass them to the function? You can directly use them from within your function without passing them through args. Passing the args is the problem here.
And are you using the static keyword to keep them private to the file? otherwise, avoid the static.

What is the data type of the name of a struct

If I wanted to make a function which takes the name of a struct as an argument, what would the method signature look like?
typedef struct Class{
} Class;
main()
{
Class *a = malloc(Class);
return instanceOf(a, Class);
}
What would the declaration of instanceOf look like?
You can't pass types to functions in C. However, you can simulate this behaviour using macros:
#define new_instance(t) (malloc(sizeof(t)))
Class *instance = new_instance(Class);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define type(x) #x
typedef struct Class{
char* type;
} Class;
Class *Class_new(){
Class *v;
v=(Class*)malloc(sizeof(Class));
v->type = "Class";
return v;
}
void Class_free(Class *a){
free(a);
}
int instanceOf(Class *a, const char* type){
return strcmp(a->type, type) == 0;
}
int main(){
Class *a = Class_new();
printf("%s\n", instanceOf(a, type(Class)) ? "YES" : "NO");
Class_free(a);
return 0;
}
// Encode and encapsulate the type within a nested structure when you create it.
struct struct_info
{
int type;
char name[32];
}
struct mystruct
{
struct struct_info;
}

Resources