【问题标题】:Converting uint8_t to int issues将 uint8_t 转换为 int 问题
【发布时间】:2014-10-22 22:49:16
【问题描述】:

我正在尝试通过串行通信与 USB 加密狗进行通信。我的通信正常,但是我无法让设备正确解析通信。我的设备读取消息并将其与硬编码的 c 字符串进行比较。它解析并识别出它是正确的字符串,但是当我尝试解析 : 字符之后的值时,它返回 0x00000000 我不知道为什么。我尝试过使用 char cast 和 atoi,我尝试过使用简单的 ascii 翻译,甚至还进行了按位加法运算,如下所示:convert subset of vector<uint8_t> to int

例如:
我发送“心率:55” 它解析并识别出“心率:”但是当我告诉它去找 55 并把它带回来做一些事情时,它给了我一个 0x00000000
这是一个sn-p:

const uint8_t hrmSet[] = "Heart Rate:";

/** Find the : character in the string and break it apart to find if it matches, 
and determine the value of the value of the desired heart rate. **/
int parse(uint8_t *input, uint8_t size)
{
    for (uint8_t i = 0; i < size; i++)
    {
        if (input[i] == ':')
        {
            if (compare_string(input, hrmSet, i) == 0)
            {
                int val = 0;
                for (int j = i+1; j < size; j++)
                {
                    if (!isdigit(input[j]))
                    {
                        for (int k = i; k < j; k++)
                        {
                            val <<= 8;
                            val |= input[k];
                        }
                    }   
                }
                return val;
            }
            return -1;
        }
    }
    return -1;
}

比较字符串函数

/** Compare the input with the const values byte by byte to determine if they are equal.**/
int compare_string(uint8_t *first, const uint8_t *second, int total)
{
    for (int i = 0; i < total; i++)
    {
        if (*first != *second)
        {
            break;
        }

        if (*first == '\0' || *second == '\0')
        {
            break;
        }

        first++;
        second++;
    }

    if (*first == ':' && *second == ':')
    {
        return 0;
    }
    else
    {
       return -1;
    }
}

【问题讨论】:

  • 为什么要在 找到冒号后进行字符串比较?
  • 你为什么要检查 not isdigitk 循环的目的是什么?
  • 您的 compare_string 每次调用时都会从两个字符串(inputhrmSet)的开头进行迭代。
  • compare_string 函数可以通过break在任一字符串中找到冒号时循环来改进。这样,您就不必在调用 compare_string 之前搜索冒号,也不需要 total 作为参数。
  • 我找到了冒号,用来设置 compare_string 测试的界限。因为我不知道价值会持续多久。将来,这将检查多个不同的字符串是否匹配。
    我再次检查 not isdigit 以找到字符串的结尾,因为我不知道每次会多长时间。
    因为这个相关的问题,所以出现了 K 循环:stackoverflow.com/questions/17813350/…

标签: c serial-communication rs485


【解决方案1】:

这里的问题是您正在使用嵌套循环来执行应该使用顺序循环来完成的任务。

例如,i 循环搜索冒号,然后compare_string 中的循环再次搜索冒号。您可以先运行i 循环,然后在i 循环完成后调用compare_string。但是更好的设计是让compare_string在比较时搜索冒号,然后返回冒号后面的字符的索引(如果没有找到冒号,则返回-1)。

jk 嵌套循环也是如此。 j 循环正在搜索数字的结尾。 k 循环只在j 循环完成后运行一次,因此k 循环应该在j 循环之后,而不是嵌套。但更好的设计是在搜索数字末尾的同时转换数字的单个循环。

下面的代码演示了一种使用我描述的技术的可能实现。

const uint8_t hrmSet[] = "Heart Rate:";

int compare_string( uint8_t *input, const uint8_t *expected, int size )
{
    for ( int i = 0; i < size; i++ )
    {
        if ( *input != *expected || *expected == '\0' )
            return( -1 );

        if ( *input == ':' && *expected == ':' )
            return( i + 1 );

        input++;
        expected++;
    }

    return( -1 );
}

int parse( uint8_t *input, uint8_t size )
{
    int i, val;

    if ( (i = compare_string( input, hrmSet, size )) < 0 )
        return( -1 );

    val = 0;
    for ( ; i < size && isdigit( input[i] ); i++ )
        val = val * 10 + input[i] - '0';

    return( val );
}

int main( void )
{
    uint8_t input[] = "Heart Rate:75";
    int rate = parse( input, sizeof(input) - 1 );
    printf( "%d\n", rate );
}

【讨论】:

  • 非常感谢!查看我的代码,我认为所有循环都像他们想象的那样中断,但显然有些事情没有按预期工作,而且很复杂。毕竟,简单才是终极的复杂。
【解决方案2】:
int val = 0;
for(int j = i+1; j < size; j++){
    if(isdigit(input[j] )){
        val = val * 10 + input[j]-'0';// val = (val << 8) | input[j];
    }   
}
return val;

【讨论】:

  • @meaning-matters 虽然我个人同意你的编码风格(关于大括号的位置),但你应该意识到,仅仅为了强加你喜欢的风格而编辑某人的帖子被认为是非常不礼貌的。
  • 您在下面的回答表明我们不同意编码风格。但我同意这很粗鲁。下次会三思而后行。 (我坚信糟糕的编码风格是软件领域出现大量垃圾的原因。极其干净/一致的格式是工艺的一部分。)
  • 代码拉长垂直影响思维。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多