【问题标题】:Pebble AppMessage JS json/csv -> CPebble AppMessage JS json/csv -> C
【发布时间】:2015-10-09 21:28:06
【问题描述】:

我正在试验 Pebble SDK,并想从网络上读取太阳能数据。 我已经设法完全用 JS 构建了一个应用程序。请参阅此link

由于我在 JS 中发现了一些限制,我正在用 C 重写代码。 通过 JS 接收 json 数据时,我通过字典将其发送给 C。 可以找C版here

从网络收到的 RAW 数据:

[ { HourNum: "0:0", HourPower: "0" }, { HourNum: "0:10", HourPower: "0" }, { HourNum: "0:20", HourPower: "0" } 等

过滤“HourPower”数据并通过字典选项发送到 C:

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59, 72,89,110,127,160,192,253,316,352,360,522,539,601,598,770,582,650,810,741,805,894,908,864,904,962,1016,1106,1853,1503,1311,1406,1444,1401,1409,1344,1622,1472,1382,1609,1766,3310,3093,2041,1496,2068,3302,3185,1358, 2760,2715,1285,994,1086,832,871,813,1707,1218,1218,239,203,170,132,70,53,45,39,39,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0]

两个挑战:

  • 1 我想知道我是否已收到所有 144 个条目。

在日志中我只看到:

收到的buffer_solar值: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,

JS和C之间的数据有限制吗? 在将数据从 JS 发送到 C 之前,是否需要将数据拆分为多个部分?

  • 2 我不知道如何处理 C 中接收到的数据。** 我已经阅读并尝试了几种可能性,尝试读取本机 json,现在尝试通过 csv 读取它,但是如何?

最终目标是从网络上读取这些值并创建图表。 但首先我需要正确读取 C 中的值。

我是否正确我应该采用 csv 方式? 任何有 JS 和 C 之间“更大”数据集经验的人?

【问题讨论】:

    标签: c csv pebble-sdk


    【解决方案1】:

    我不能在 CloudPebble 中使用 strtok,所以我写了这个函数来推进指向下一个数字的指针

    void skip_over_char(char **buffer, const char lookup) {
      while(((*buffer)[0] != lookup) && ((*buffer)[0] != '\0')) {
        (*buffer)++;
      }
      (*buffer)++; //skip over lookup character
    }
    

    然后您可以通过这种方式将值添加到 solar_values 数组中。结果,您可以看到您确实收到了所有 144 个条目。

    static int solar_values[144];
    static int index;
    static int received;
    char *pch;
    
    case KEY_SOLARVALUE :
      received = snprintf(buffer_solarvalue, sizeof(buffer_solarvalue), "%s", t->value->cstring);
      APP_LOG(APP_LOG_LEVEL_INFO , "Received buffer_solarvalue: %s", buffer_solarvalue);
      pch = buffer_solarvalue;
      skip_over_char(&pch, '[');
      index = 0;
      while (pch - buffer_solarvalue < received) {
        solar_values[index++] = atoi(pch);
        APP_LOG(APP_LOG_LEVEL_INFO, "solar_values[%3d] = %d", index - 1, solar_values[index-1]);
        skip_over_char(&pch, ',');
      }
      APP_LOG(APP_LOG_LEVEL_INFO , "Received %d values", index);
      break;  
    

    【讨论】:

    • 感谢你们为我指出似乎合乎逻辑的方向。我还测试了一个字典条目可以容纳多少条目。我想出的答案是 58 个字符,例如: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 如果我要发送 nr: 1000 或 2000 之类的数据,我只能发送 ± 9 个数据条目,这样一共有 16 个字典条目.由于16个条目没有意义,我需要找到一种方法来分批发送数据:发送数据batch1,等待确认,发送下一批。这是学习 C 和 Pebble 工作方式的一个很好的步骤。
    【解决方案2】:

    如果您想读取144 值,您要做的第一件事就是发送144 值进行转换。您的数据仅包含138

    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59, 72,89,110,127,160,192,253,316,352,360,522,539,601,598,770,582,650,810,741,805,894,908,864,904,962,1016,1106,1853,1503,1311,1406,1444,1401,1409,1344,1622,1472,1382,1609,1766,3310,3093,2041,1496,2068,3302,3185,1358, 2760,2715,1285,994,1086,832,871,813,1707,1218,1218,239,203,170,132,70,53,45,39,39,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0]

    您有多种选择将 csv 数据转换为数字。 strtokstrsep,或者我个人的选择strtol。原因是对于数值转换,strtol(及其姊妹函数)在转换失败时提供最大程度的错误报告。

    由于strtol (const char *nptr, char **endptr, int base); 使用指向要转换的数字的指针 (nptr) 并更新指向刚刚转换的数字后面的下一个字符的结束指针 (endptr),因此非常适合步行向下由 any 分隔符分隔的一串数字,并将所有值转换为数字。

    以下只是一个快速示例,说明如何使用它将“HourPower”数据 转换为包含在数组中的单个整数。出于示例的目的,您的值只是从stdin 中读取的。我提供了松散的错误检查,只是为了捕获一些基本错误,否则这些错误会导致超出数组末尾的写入等。它们是错误检查的示例,并非详尽无遗。

    查看一下,如果您有任何问题,请告诉我:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
    #include <errno.h>
    
    #define NDATA 160
    #define MAXC 1024
    
    long xstrtol (char *p, char **ep, int base);
    
    int main (void) {
    
        char line[MAXC] = {0};              /* line buffer for fgets    */
        char *p, *ep;                       /* pointers for strtol      */
        int array[NDATA] = {0};             /* array of values          */
        size_t idx = 0, nelem = 0;          /* indexes, number of ints  */
    
        /* read each line in file */
        while (fgets(line, MAXC, stdin))
        {
            p = ep = line;  /* initize pointer/end pointer      */
    
            /* convert each csv value to number, store in array */
            while (errno == 0)
            {
                /* skip delimiters/move pointer to next digit */
                while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
                if (*ep)
                    p = ep;
                else  /* break if end of string */
                    break;
    
                array[idx++] = (int)xstrtol (p, &ep, 10); /* convert */
    
                if (idx == NDATA) { /* NDATA reached, conversion error */
                    fprintf (stderr, "error: conversion exceeded 144.\n");
                    return 1;
                }
    
            }
    
            if (idx != 144)   /* validate 144 values converted */
                fprintf (stderr, "warning: invalid conversion of '%zu' values.\n",
                        idx);
    
            nelem = idx;  /* save the final number of values (144) */
        }
    
        printf ("\n the converted json values are:\n\n");
        for (idx = 0; idx < nelem; idx++) {
            printf ("  array[%2zu] : %d\n", idx, array[idx]);
        }
        putchar ('\n');
    
        return 0;
    }
    
    /** a simple strtol implementation with error checking.
    *  any failed conversion will cause program exit. Adjust
    *  response to failed conversion as required.
    */
    long xstrtol (char *p, char **ep, int base)
    {
        errno = 0;
    
        long tmp = strtol (p, ep, base);
    
        /* Check for various possible errors */
        if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
            (errno != 0 && tmp == 0)) {
            perror ("strtol");
            exit (EXIT_FAILURE);
        }
    
        if (*ep == p) {
            fprintf (stderr, "No digits were found\n");
            exit (EXIT_FAILURE);
        }
    
        return tmp;
    }
    

    示例输出

    $ ./bin/array_json_xstrtol <hpdata.txt
    warning: invalid conversion of '138' values.
    
     the converted json values are:
    
      array[ 0] : 0
      array[ 1] : 0
      array[ 2] : 0
      array[ 3] : 0
      array[ 4] : 0
      array[ 5] : 0
      array[ 6] : 0
      array[ 7] : 0
      array[ 8] : 0
      array[ 9] : 0
      array[10] : 0
    ...
      array[47] : 59
      array[48] : 72
      array[49] : 89
      array[50] : 110
      array[51] : 127
      array[52] : 160
      array[53] : 192
      array[54] : 253
      array[55] : 316
      array[56] : 352
      array[57] : 360
      array[58] : 522
      array[59] : 539
    ...
      array[130] : 0
      array[131] : 0
      array[132] : 0
      array[133] : 0
      array[134] : 0
      array[135] : 0
      array[136] : 0
      array[137] : 0
    

    hpdata.txt 包含您的示例数据。

    【讨论】:

    • 你是对的,大约只有 138 个。太阳数据可以增长一整天到 144 个。(每 10 分钟,每 24 小时)。感谢您的扩展回答!
    • 很高兴为您提供帮助。希望您可以利用其中的一些。我在数据解析/数值转换方面做了很多工作,这是处理它的最灵活和最可靠的方法。如果您使用strtokstrsep,它们所做的只是将值分开,您仍然需要完成将字符串转换为数字的过程——这一切都在一次完成,使用endptr 的方式本来打算...
    猜你喜欢
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    相关资源
    最近更新 更多