In simple C, how do you make the equivalent of a "card"?

So, I am trying to make the program completely from scratch (without libraries), and I have a function that is very ugly:

int parseUnsignedInt ( char * ch, unsigned int * ui ) { /* Starting at character ch, reads the unsigned int into the variable ui, returns the number of characters read. */ ui = 0; // unsigned integer into which the string representation is read int m = 1; // multiplier int ncp = 0; // # of characters parsed while (*ch) { bool chid = false; // ch is a decimal for (int k = 0; k < decmapLength; ++k) { if (decmap[k].cval == *ch) { ui += decmap[k].ival * m; m *= 10; chid = true; break; } } if (!chid) break; ++ncp; ++ch; } return ncp; } 

Part of its ugliness stems from the fact that I need a way to associate char actors with int egers ('0' โ†’ 0, '1' โ†’ 1, ..., '9'-> 9) and made an array or structures

 typedef struct icpair { char cval; int ival; } icpair; icpair decmap [10] = {{'0',0}, {'1',1}, {'2',2}, {'3',3}, {'4',4}, {'5',5}, {'6',6}, {'7',7}, {'8',8}, {'9',9}}; int decmapLength = sizeof(decmap)/sizeof(icpair); 

for this purpose. But looking at the value, if it even exists, takes into account the unsightly number of lines that can be compressed if there is a better way to do it in pure C. I also want it to be reliable, so no subtraction of the ASCII value, for example '9'-'ch' . Is this possible in pure C, and if so, how is this implemented?

+6
source share
2 answers

A simple map API in C might look like this:

 Map * map_create(void); void map_insert(Map * map, char key, int value); int map_find(Map * map, char key); void map_destroy(Map * map); 

Then you can do map_find(map, '0') to get an integer value, possibly with a return semantics of -1 if it is not found.

This can be done using several different data structures depending on your needs. If you don't care about maintaining order, a hash table is likely to be the most appropriate. If you need to support key-based ordering, for example, a binary tree might be better (perhaps a red-black tree).

You can change the API to take void * for the key, and generalize it a little for the value (in the absence of generics that are not in C). Complexity will be added, for example, providing a hash function for a hash table or a comparison function for a binary tree.

However, making *ch - '0' safe and will work just fine.

+1
source

If you want to match any 10 random characters with 0..9 , you donโ€™t need a separate ival structural element - the โ€œnatural orderโ€ already indexes the correct digit right away. This way you can use a single char array with a length of 10 random characters as a search.

If the characters in this array sequentially increase by 1, you do not need an array at all. In this case, you can subtract the first code, check if the result is from 0 to 9, which indicates success, or reject the character otherwise.

This is true for dialing in C because it requires the C specification:

In both basic source and execution character sets, the value of each character after 0 in the above list should be greater than the value of the previous one. ( 5.2.1 Character sets in ISO / IEC 9899: Regulatory project 201x (2011) )

Thus, to get a numeric value for any digit, character - '0' always true.

As a note, this is not defined for the ranges A..Z and A..Z . This means that if you treat 'A' as 0 , then it is not guaranteed that 'J'-'A' == 9 . To do this, you need a simple array of search characters.

0
source

Source: https://habr.com/ru/post/986020/


All Articles