如何连接 const char* 以通过 https 获取另一个 JSON

如何解决如何连接 const char* 以通过 https 获取另一个 JSON

在使用带有 ArduinoJSON 库的 ESP32 板响应 JSON 后,我尝试多次获取 JSON(YouTube 数据 API)(以获取 activeLiveChatId 和评论)。但我无法连接 const char 值来创建新 URL。也许我的代码处理 const char* 应该是错误的。 你能给我建议一些解决方案吗?下面是我的草图。

#include <string>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <stdlib.h>

// Fingerprint for demo URL,expires on June 2,2021,needs to be updated well before this date

char ssid[] = "myssid";       // your network SSID (name)
char password[] = "mypass";  // your network key

#define API_KEY "myapikey"  // your google apps API Token
#define CHANNEL_ID "mychannelid" // makes up the url of channel
#define servername "www.googleapis.com"

WiFiClientSecure client;

void setup() {
  Serial.begin(115200);
  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid,password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  delay(3000);

  if ((WiFi.status() == WL_CONNECTED)) {
    String url1 = ("https://"servername"/youtube/v3/search?eventType=live&part=id&channelId="CHANNEL_ID"&type=video&key="API_KEY);
    String url2prefix = "https://"servername"/youtube/v3/videos?part=liveStreamingDetails&field=activeLiveChatId&id=";
    String url2postfix = "&key="API_KEY;
    const char* items_0_id_videoId;
    HTTPClient https;
    
    Serial.print("[HTTPS] begin...\n");
    if (https.begin(client,url1)) {  // HTTPS
      Serial.print("[HTTPS] GET...\n");
      // start connection and send HTTP header
      int httpCode = https.GET();
      // httpCode will be negative on error
      if (httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTPS] GET... code: %d\n",httpCode);
        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = https.getString();
          DynamicJsonDocument doc(96);
          StaticJsonDocument<64> filter;
          filter["items"][0]["id"]["videoId"] = true;
          DeserializationError error = deserializeJson(doc,payload,DeserializationOption::Filter(filter));
          if (error) {
            Serial.print(F("deserializeJson() failed: "));
            Serial.println(error.c_str());
            return;
          }
 
          const char* kind = doc["kind"]; // "youtube#searchListResponse"
          const char* etag = doc["etag"]; // 
          const char* regionCode = doc["regionCode"]; // "JP"
          int pageInfo_totalResults = doc["pageInfo"]["totalResults"]; // 1
          int pageInfo_resultsPerPage = doc["pageInfo"]["resultsPerPage"]; // 1
          JsonObject items_0 = doc["items"][0];
          const char* items_0_kind = items_0["kind"]; // "youtube#searchResult"
          const char* items_0_etag = items_0["etag"]; // 
          const char* items_0_id_kind = items_0["id"]["kind"]; // "youtube#video"
          items_0_id_videoId = items_0["id"]["videoId"]; // 

          Serial.printf(
          "ID: %s\n",items_0_id_videoId);
        }
      }
    }
    String url2 = url2prefix + items_0_id_videoId + url2postfix;
    //retrieve activeLiveChatId
    if (https.begin(client,url2)) {  // HTTPS
      Serial.print("[HTTPS] GET...\n");
      // start connection and send HTTP header
      int httpCode = https.GET();
      // httpCode will be negative on error
      if (httpCode > 0) {
        // HTTP header has been send and Server response header has been handled
        Serial.printf("[HTTPS] GET... code: %d\n",httpCode);
        // file found at server
        if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
          String payload = https.getString();
          Serial.println(payload);
          // Stream& input;
          DynamicJsonDocument doc(96);
          StaticJsonDocument<64> filter;
          filter["items"][0]["liveStreamingDetails"]["activeLiveChatId"] = true;
          DeserializationError error = deserializeJson(doc,DeserializationOption::Filter(filter));

          if (error) {
            Serial.print(F("deserializeJson() failed: "));
            Serial.println(error.c_str());
            return;
          }
  
          const char* items_0_liveStreamingDetails_activeLiveChatId = doc["items"][0]["liveStreamingDetails"]["activeLiveChatId"];
        
          Serial.printf(
          "livechatID: %s\n",items_0_liveStreamingDetails_activeLiveChatId
          );
        }
      } else {
        Serial.printf("[HTTP] GET... failed,error: %s\n",https.errorToString(httpCode).c_str());
      }
      https.end();
    } else {
      Serial.printf("[HTTP] Unable to connect\n");
    }
  }
}  

void loop() {
  // wait for WiFi connection
  Serial.println("Wait 10s before next round...");
  delay(10000);
}

解决方法

您从 JSON 解析器获得了 const char* 类型的只读字符串 - 没关系。您可以无限制地连接它们,但您必须提供内存来保存连接的结果。

有几种方法可以解决这个问题

  1. strncat()(很好的老式 C)。看看这个thread explaining strcat()。本质上,分配足够的内存来保存新字符串,然后将连接结果存储在那里(为清楚起见省略了错误处理)。假设您要连接的字符串是 str1str2
    const size_t cat_buf_len = strlen(str1) + strlen(str2) + 1;
    char* cat_buf = (char*) malloc(cat_buf_len);
    strncpy(cat_buf,str1,cat_buf_len);
    strncat(cat_buf,str2,cat_buf_len - strlen(cat_buf));
    // ... use the concatenated string in cat_buf
    free(cat_buf); 
  1. snprintf() (C)。与 strcat() 类似 - 看起来更容易一些,但效率不高。
    const size_t cat_buf_len = strlen(str1) + strlen(str2) + 1;
    char* cat_buf = (char*) malloc(cat_buf_len);
    snprintf(cat_buf,cat_buf_len,"%s%s",str2);
    // ... use the concatenated string in cat_buf
    free(cat_buf); 
  1. Arduino String (C++)。 String 类型在堆上操作,管理自己的内存,使用起来更容易一些。但是,如果不小心使用,它确实存在堆碎片化的风险。
    String cat_str = String(str1) + str2;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res