docs/Writerside/topics/map.h.md

changeset 1249
aad755d296a7
parent 1245
721e2032fa25
child 1250
80a1d63ede19
equal deleted inserted replaced
1248:fc5e63b04281 1249:aad755d296a7
27 > If you want to lazy-initialize maps, you can use the global `cxEmptyMap` symbol as a placeholder instead of using a `NULL`-pointer. 27 > If you want to lazy-initialize maps, you can use the global `cxEmptyMap` symbol as a placeholder instead of using a `NULL`-pointer.
28 > While you *must not* insert elements into that map, you can safely access this map or create iterators. 28 > While you *must not* insert elements into that map, you can safely access this map or create iterators.
29 > This allows you to write clean code without checking for `NULL`-pointer everywhere. 29 > This allows you to write clean code without checking for `NULL`-pointer everywhere.
30 > You still need to make sure that the placeholder is replaced with an actual map before inserting elements. 30 > You still need to make sure that the placeholder is replaced with an actual map before inserting elements.
31 31
32 ## Overview 32 ## Examples
33 33
34 <warning> 34 ```C
35 TODO: example 35 #include <stdio.h>
36 </warning> 36 #include <cx/hash_map.h>
37
38 int main() {
39 CxMap *contacts = cxHashMapCreateSimple(CX_STORE_POINTERS);
40
41 // Build a small phone book
42 cxMapPut(contacts, "John", "123-0815");
43 cxMapPut(contacts, "Jane", "987-4711");
44 cxMapPut(contacts, "Michelle", "555-3141");
45 cxMapPut(contacts, "Oliver", "000-9999");
46
47 // Retrieve a phone number
48 const char *janes_phone = cxMapGet(contacts, "Jane");
49 printf("The number of Jane is: %s\n", janes_phone);
50
51 // Update number
52 cxMapPut(contacts, "Jane", "987-1337");
53
54 // Remove and retrieve number
55 cxMapRemoveAndGet(contacts, "Jane", &janes_phone);
56 printf("The number of Jane was: %s\n", janes_phone);
57 janes_phone = cxMapGet(contacts, "Jane");
58 if (janes_phone == NULL) printf("Jane's number was deleted.\n");
59
60 // Iterate through the contact list
61 CxMapIterator iter = cxMapIterator(contacts);
62 cx_foreach(CxMapEntry *, entry, iter) {
63 cxstring name = cx_strn(entry->key->data, entry->key->len);
64 const char *phone = entry->value;
65 printf("%.*s: %s\n", (int) name.length, name.ptr, phone);
66 }
67
68 cxMapFree(contacts);
69
70 return 0;
71 }
72 ```
73
74 The above example illustrates basic operations with a map.
75
76 In the first part we add several entries to the map.
77 Then the example shows retrieval, updating, and removal of information.
78 The last part shows how to iterate over the pairs of the map and how to recover the string from the key.
79
80 In real world situations, however, it is quite unlikely that you will use a map to store string literals.
81 The next example shows a more realistic program, where it is necessary to store strings based on user input.
82
83 ```C
84 #include <stdio.h>
85 #include <string.h>
86 #include <cx/hash_map.h>
87
88 int main() {
89 // store strings in the map...
90 CxMap *contacts = cxHashMapCreateSimple(sizeof(cxmutstr));
91 // ...which are automatically freed when removed
92 cxDefineDestructor(contacts, cx_strfree);
93
94 // build a small interactive program
95 const unsigned buffer_size = 256;
96 char input[buffer_size];
97 bool running = true;
98
99 while (running) {
100 puts("\n*** Contacts - Menu ***");
101 puts("1) Add entry");
102 puts("2) Look up entry");
103 puts("3) Remove entry");
104 puts("4) Show all entries");
105 puts("0) Exit");
106 fputs("> ", stdout);
107
108 if (fgets(input, buffer_size, stdin)) {
109 if (input[1] != '\n') {
110 puts("Please select a menu item.\n");
111 } else if (input[0] == '1') {
112 fputs("Name > ", stdout);
113 if (fgets(input, buffer_size, stdin)) {
114 // Copy the name (alternative: use 2nd input buf)
115 cxmutstr name = cx_strdup(
116 cx_strn(input, strcspn(input, "\n")));
117 fputs("Phone > ", stdout);
118 if (fgets(input, buffer_size, stdin)) {
119 // add the entry, note that only the contents
120 // of the cxmutstr are copied, not the string
121 // data - therefore we have to call cx_strdup
122 cxmutstr phone = cx_strdup(
123 cx_strn(input, strcspn(input, "\n")));
124 // note, that we can simply use the cxmutstr
125 // for the name as key, because cxMapPut uses
126 // generic selection
127 cxMapPut(contacts, name, &phone);
128 }
129 cx_strfree(&name);
130 }
131 } else if (input[0] == '2') {
132 fputs("Name > ", stdout);
133 if (fgets(input, buffer_size, stdin)) {
134 // Look up the name
135 input[strcspn(input, "\n")] = '\0';
136 cxmutstr *phone = cxMapGet(contacts, input);
137 if (phone == NULL) {
138 puts("No record.");
139 } else {
140 printf("Result: %.*s\n",
141 (int) phone->length, phone->ptr);
142 }
143 }
144 } else if (input[0] == '3') {
145 fputs("Name > ", stdout);
146 if (fgets(input, buffer_size, stdin)) {
147 // Remove the entry
148 // Since we registered cx_strfree as destructor,
149 // the memory is automatically freed
150 input[strcspn(input, "\n")] = '\0';
151 if (cxMapRemove(contacts, input)) {
152 puts("No such record.");
153 } else {
154 puts("Removed.");
155 }
156 }
157 } else if (input[0] == '4') {
158 // Almost the same iteration loop as above ...
159 CxMapIterator iter = cxMapIterator(contacts);
160 cx_foreach(CxMapEntry *, entry, iter) {
161 cxstring name = cx_strn(entry->key->data,
162 entry->key->len);
163 // ... except that here we get cxmutstr*
164 cxmutstr *phone = entry->value;
165 printf("%.*s: %.*s\n",
166 (int) name.length, name.ptr,
167 (int) phone->length, phone->ptr);
168 }
169 } else if (input[0] == '0') {
170 running = false;
171 } else {
172 puts("Please select a menu item.\n");
173 }
174 } else {
175 running = false;
176 }
177 }
178
179 // this will free all remaining strings that are in the map
180 cxMapFree(contacts);
181
182 return 0;
183 }
184 ```
37 185
38 > In the following Sections, the type for the key is denoted `KeyType`. 186 > In the following Sections, the type for the key is denoted `KeyType`.
39 > All functions are implemented as generics, so that the following types are supported: 187 > All functions are implemented as generics, so that the following types are supported:
40 > `CxHashKey`, `cxstring`, `cxmutstr`, `const char*`, and `char*`. 188 > `CxHashKey`, `cxstring`, `cxmutstr`, `const char*`, and `char*`.
41 > {style="note"} 189 > {style="note"}

mercurial