如何逐个字母地考虑字符串并将它们与 if 函数进行比较?

问题描述 投票:0回答:2

我尝试从字符串中逐个字母获取并将它们用作函数的参数,该函数将该字母标识为“a”或“b”或“c”......然后为变量提供一些值并返回该值值为十六进制值。

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;
}

但是我没有按照我的预期返回值。返回的值与我的预期有很大不同。我找不到哪里出了问题。

c string function avr atmega32
2个回答
1
投票

您的尝试失败的原因是您向需要

char
的函数传递了
char *
值。由于参数预计是一个字符串,并且您的函数代码预计该字符串仅为单个字符,因此您必须更改函数的匹配方式,或更改函数参数以匹配您调用它的方式。

后者更容易。

unsigned int brail_print(char character){

要将一个字符与另一个字符进行比较,您可以使用

==
。您可以使用
tolower()
将字符转换为小写以简化比较。

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

但是,对于您的应用程序,您似乎想将字母映射到十六进制值。这种映射可以通过表格来实现。您可以从两个数组动态初始化表。一个代表字母,另一个代表十六进制值。

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)];
}

也可以静态初始化表。我只是懒得把它全部打出来,但先开始吧:

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

使用静态表,可以进一步简化建议的功能。

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

    if (!isalpha(character)) return 0;
    return map[tolower(character)];
}

1
投票

OP 的帖子中缺少代码。

无论如何,OP的问题很容易理解并且可以提供指导。

一系列

if()/else if()
条件(每个条件调用两个函数调用)是一种昂贵、乏味且容易出错的方法。


正如 @jxh 所提议的,静态“查找表”是一个简单的解决方案。

基于 7 位 ASCII,这是 128 个条目,其中填写了

A
-
Z
a
-
z
0
-
9
SP
','
。一个好的开始...您可以根据需要在表格中仔细添加更多标点符号。 (请注意,
'&'
仍然翻译为
'00'
。)

SP
返回为
20
。更多代码可能只是输出空白,而不是将其转换为 ASCII 十六进制值。

有些角色需要更多的复杂性,转换为多个 Brail 角色,但这只是一个开始。另外,“移位寄存器切换到/从“数字””也留给您添加。

(填写此表的

hex
值已从您的问题中复制。我尚未验证每个值是否正确。)

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( void ) {
    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

由于 Brail 字符集由两列 3 个引脚组成,因此您可以更轻松地处理

octal
表示,而不是
hexadecimal
。供您考虑:

#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( void ) {
    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);
}

输出:

   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

事实上,知道这些是

octal
值,并且“左/右”在这种表示中交换,两个八进制数字漂亮地映射到盲文字母表。

 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
© www.soinside.com 2019 - 2024. All rights reserved.