2

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.

  • 1
    `if (tolower(character) == 'a') {` – jxh Sep 10 '22 at 23:10
  • 1
    You need to enable warnings, and fix them. You're passing characters (which are promoted to integers due to the missing forward declaration) where pointers are expected. And of course, you're missing a forward declaration for `brail_print`. So add the missing forward, enable warnings, and fix the warnings. – Tom Karzes Sep 10 '22 at 23:19
  • if (character == 'a' || character == 'A') – Maxwell D. Dorliea Sep 10 '22 at 23:24

2 Answers2

1

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)];
}
jxh
  • 69,070
  • 8
  • 110
  • 193
  • Is there any way to map two chars for one hex value in the table?? as an example both 'a' and 'A' chars map to 0x01. – Mihiranga Silva Sep 11 '22 at 07:40
  • Yes, it is possible. But the code shown in my answer uses `tolower()`, so only the lowercase letters need to be mapped. – jxh Sep 11 '22 at 14:52
  • @jxh Just posted EDIT to my answer... We had both missed the _natrual fit_ of expressing Brail 'dots' (2x3 grid) in octal rather than hex... Oh well... 016 023 012 036 SP 023 001 017 017 021 035 016 `:-)` – Fe2O3 Sep 11 '22 at 15:45
1

As @jxh proposed, a static "look up table" is the solution.

Based on 7-bit ASCII, this is 128 entries with A-Z, a-z, 0-9, SP and ',' filled in. A good start... You can carefully add more punctuation to the table as you need. (Notice that '&' still translates to '00'.)

SP comes back as 20... More code might just output a blank instead of translating it to the ASCII hex value.

Some characters will need more complexity, translating to multiple Brail characters, but this is a start. Also "shifting" in/out of digits is left for you to add.

(The hex values filling this table have been copied from your question. I've not checked each & every value as being correct.)

unsigned int brail_print( char c ) {
    unsigned char brail[] = {
        // CTRL codes
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // CTRL codes
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        // punctuation
        0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
        // punctuation & digits
        0x00, 0x01, 0x03, 0x09, 0x19, 0x11, 0x0B, 0x1B, 0x13, 0x0A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00,
        // @ + A-O
        0x00, 0x01, 0x03, 0x09, 0x19, 0x11, 0x0B, 0x1B, 0x13, 0x0A, 0x1A, 0x05, 0x07, 0x0D, 0x1D, 0x15,
        // P-Z + braces
        0x0F, 0x1F, 0x17, 0x0E, 0x1E, 0x25, 0x27, 0x3A, 0x2D, 0x3D, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
        // ` + a-o
        0x00, 0x01, 0x03, 0x09, 0x19, 0x11, 0x0B, 0x1B, 0x13, 0x0A, 0x1A, 0x05, 0x07, 0x0D, 0x1D, 0x15,
        // p-z + braces
        0x0F, 0x1F, 0x17, 0x0E, 0x1E, 0x25, 0x27, 0x3A, 0x2D, 0x3D, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
    };
    
    return brail[ c ];
}

int main() {
    char str[] = "The Cat sat, & purred, on the Mat. 123";

    int i;
    for( i = 0; str[ i ]; i++ )
        printf( "%c  ", str[ i ] );
    putchar( '\n' );

    for( i = 0; str[ i ]; i++ )
        printf( "%02X ", brail_print( str[ i ] ) );
    putchar( '\n' );

    return (0);
}

T  h  e     C  a  t     s  a  t  ,     &     p  u  r  r  e  d  ,     o  n     t  h  e     M  a  t  .     1  2  3
1E 13 11 20 09 01 1E 20 0E 01 1E 02 20 00 20 0F 25 17 17 11 19 02 20 15 1D 20 1E 13 11 20 0D 01 1E 00 20 01 03 09

EDIT: Since the Brail character set is composed of two columns of 3 pins, you may make your life easier dealing with octal representations, rather than hexadecimal. For your consideration:

#include <stdio.h>

unsigned int brail_printOCT( char c ) {
    unsigned char oct[] = {
    // CTRL codes
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    // CTRL codes
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
    // punctuation
    040,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 002,   0,   0,   0,
    // punctuation & digits
      0, 001, 003, 011, 031, 021, 013, 033, 023, 012, 032,   0,   0,   0,   0,   0,
    // @ + A-O
      0, 001, 003, 011, 031, 021, 013, 033, 023, 012, 032, 005, 007, 015, 035, 025,
    // P-Z + braces
    017, 037, 027, 016, 036, 045, 047, 072, 055, 075, 065,   0,   0,   0,   0,   0,
    // ` + a-o
      0, 001, 003, 011, 031, 021, 013, 033, 023, 012, 032, 005, 007, 015, 035, 025,
    // p-z + braces
    017, 037, 027, 016, 036, 045, 047, 072, 055, 075, 065,   0,   0,   0,   0,   0,
    };
    return oct[ c ];
}

int main() {
    char str[] = "AaBbCc xyz , & 123";

    int i;
    for( i = 0; str[ i ]; i++ )
        printf( "%4c ", str[ i ] );
    putchar( '\n' );

    for( i = 0; str[ i ]; i++ )
        printf( " %03o ", brail_printOCT( str[ i ] ) );
    putchar( '\n' );

    return (0);
}

Output

   A    a    B    b    C    c         x    y    z         ,         &         1    2    3
 001  001  003  003  011  011  040  055  075  065  040  002  040  000  040  001  003  011

EDIT: In fact, knowing these are octal values, and that "left/right" are swapped in this representation, two octal digits map beautifully to the Brail alphabet.

 S  t  u  f  f     h  a  p  p  e  n  s
16 36 45 13 13 40 23 01 17 17 21 35 16
Fe2O3
  • 6,077
  • 2
  • 4
  • 20