Search code examples
cstringfunctionavratmega32

How to consider letter by letter of a string and compare them with if functions?


I tried to get letter by letter from a string and use them as a parameter to a function that identifies that letter as "a" or "b" or "c"... and then give some value to a variable and return that value as a hex value.

char A[] = "abcdefghijklmnopqrstuvwxyz";
    int j;
    for (j=0;A[j]!=0;j++){
        
        int port_val = brail_print(A[j]);
        SOL_Port = HEX[port_val];
    }

unsigned int brail_print(char *character){
   unsigned char HEX[] = {0x01,0x03,0x09,0x19,0x11,0x0B,0x1B,0x13,0x0A,0x1A,0x05,0x07,0x0D,0x1D,0x15,0x0F,0x1F,0x17,0x0E,0x1E,0x25,0x27,0x3A,0x2D,0x3D,0x35};
   unsigned int hexval = 0;

   if      (strcmp(character,"a") == 0 || strcmp(character,"A") == 0){
    hexval = HEX[0];
   }
   else if (strcmp(character,"b") == 0 || strcmp(character,"B") == 0){
    hexval = HEX[1];
   }
   else if (strcmp(character,"c") == 0 || strcmp(character,"C") == 0){
    hexval = HEX[2];
   }
   return hexval;
}

but I didn't return values as I expected. The returned values are more different than I expected. I can not find what is wrong.


Solution

  • The reason your attempt did not work is because you passed in a char value to your function that expected a char *. Since the argument is expected to be a string, and your function code expects the string to be only a single character, you would have to change the way your function to match, or change your function parameter to match the way you are calling it.

    The latter is easier.

    unsigned int brail_print(char character){
    

    To compare a character with another character, you would use ==. You can use tolower() to convert the character to lower case to simplify the comparison.

        if (tolower(character) == 'a') {
    

    However, for your application, it seems you want to map letters to hex values. This mapping can be achieved with a table. You can initialize the table dynamically from two arrays. One representing the alphabet, the other representing the hex values.

    unsigned int brail_print (char character) {
        static _Thread_local _Bool initialized;
        static _Thread_local unsigned int map[CHAR_MAX];
        static const char letters[] = "abcdefghijklmnopqrstuvwxyz";
        static const unsigned int hexvalues[] = {
                0x01,0x03,0x09,0x19,0x11,0x0B,0x1B,
                0x13,0x0A,0x1A,0x05,0x07,0x0D,0x1D,
                0x15,0x0F,0x1F,0x17,0x0E,0x1E,0x25,
                0x27,0x3A,0x2D,0x3D,0x35
        };    
    
        if (!initialized) {
            for (int i = 0; letters[i]; ++i) {
                int j = letters[i];
                map[j] = = hexvalues[i];
            }
            initialized = true;
        }
    
        if (!isalpha(character)) return 0;
        return map[tolower(character)];
    }
    

    It is possible to initialize the table statically, too. I'm just too lazy to type it all out, but to start it off:

        static const unsigned int map[] = {
            ['a'] = 0x01,
            ['b'] = 0x03,
            //...
        };
    

    With a static table, the proposed function can be simplified further.

    unsigned int brail_print (char character) {
        static const unsigned int map[] = {
            ['a'] = 0x01,
            ['b'] = 0x03,
            //...
        };
    
        if (!isalpha(character)) return 0;
        return map[tolower(character)];
    }