Arduino把char变成了一个字符串

时间:2016-11-26 10:45:50

标签: arduino char

我正在尝试将字符串转换为字符串,以便我可以提取我感兴趣的值,但它只是显示为空。
我感兴趣的变量是内容。

我正在执行get并返回一个JSON对象。并希望提取日出和日落值。

#include <SPI.h>
#include <Ethernet2.h>
#include <String.h>
#include <stdlib.h>

EthernetClient client;

const char* server =    "api.sunrise-sunset.org";                  // server's address
const char* resource =  "/json?lat=53.440&lng=0.200&date=today";   // http resource
const unsigned long BAUD_RATE = 9600;                              // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000;                          // max respone time from server
const size_t MAX_CONTENT_SIZE = 512;                               // max size of the HTTP response

// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
initSerial();
initEthernet();
}

// ARDUINO entry point #2: runs over and over again forever
void loop() {
 if (connect(server)) {
 if (sendRequest(server, resource) && skipResponseHeaders()) {
  char response[MAX_CONTENT_SIZE]; 
  String str(response);
  Serial.println(str);


char* field;
char* sunset;
char* sunrise;

field = strtok(response,"{,");

while (field != NULL)
{
    field = strtok (NULL, ",}");

    if(field != NULL)
    {
        if(strstr(field, "sunrise") != NULL)
        {
            int length = strlen(field);
           sunrise = new char[length + 1];
           strncpy(sunrise, field, length + 1);         // +1 to copy a terminating null as well
        }

        if(strstr(field, "sunset") != NULL)
        {
            int length = strlen(field);
            sunset = new char[length + 1];              
            strncpy(sunset, field, length + 1);         // +1 to copy a terminating null as well
        }
    }
}

//Serial.println("SUNRISE DATA: %s\n\n", sunrise);
//Serial.println("SUNSET  DATA: %s\n\n", sunset);

free(sunrise);  // do not forget to free the memory if not needed anymore
free(sunset);   // do not forget to free the memory if not needed anymore
}
disconnect();
}
wait();
}
// Initialize Serial port
void initSerial() {
 Serial.begin(BAUD_RATE);
 while (!Serial) {
 ;  // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Initialize Ethernet library
void initEthernet() {
 byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
 byte ip[] = { 192,168,0,202 };

 if (!Ethernet.begin(mac)) {
  Serial.println("Failed to configure Ethernet");
  return;
  }
  Serial.println("Ethernet ready");
  delay(1000);
  }
  // Open connection to the HTTP server
  bool connect(const char* hostName) {
   Serial.print("Connect to ");
   Serial.println(hostName);

   bool ok = client.connect(hostName, 80);

   Serial.println(ok ? "Connected" : "Connection Failed!");
   return ok;
  }
  // Send the HTTP GET request to the server
  bool sendRequest(const char* host, const char* resource) {
   Serial.print("GET ");
   Serial.println(resource);
    client.print("GET ");
    client.print(resource);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
    return true;
   }
   // Skip HTTP headers so that we are at the beginning of the response's body
   bool skipResponseHeaders() {
    // HTTP headers end with an empty line
   char endOfHeaders[] = "\r\n\r\n";
   client.setTimeout(HTTP_TIMEOUT);
  bool ok = client.find(endOfHeaders);
   if (!ok) {
   Serial.println("No response or invalid response!");
   }
   return ok;
  }
 void disconnect() {
  Serial.println("Disconnect");
  client.stop();
 }
 // Pause for a 1 minute
 void wait() {
  Serial.println("Wait 60 seconds");
  delay(60000);
 }

garbled get data

1 个答案:

答案 0 :(得分:1)

我认为你方存在误解。当然,您希望处理服务器的响应,并根据您的代码,这是存储响应的char response[MAX_CONTENT_SIZE]

现在这个已经是一个字符串,或多或少。一组字符char s。来自here的定义。

  

字符串实际上是一个由空字符'\ 0'终止的一维字符数组。因此,以null结尾的字符串包含构成字符串后跟空值的字符。

您可以立即从中提取相关部分。

根据sunrise-sunset.org/api,你的回答应该是这样的。请注意,我只是将数据复制到数组中以进行测试。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_CONTENT_SIZE 512

char response[MAX_CONTENT_SIZE] = \
"{\
\"results\":\
{\
\"sunrise\":\"7:27:02 AM\",\
\"sunset\":\"5:05:55 PM\",\
\"solar_noon\":\"12:16:28 PM\",\
\"day_length\":\"9:38:53\",\
\"civil_twilight_begin\":\"6:58:14 AM\",\
\"civil_twilight_end\":\"5:34:43 PM\",\
\"nautical_twilight_begin\":\"6:25:47 AM\",\
\"nautical_twilight_end\":\"6:07:10 PM\",\
\"astronomical_twilight_begin\":\"5:54:14 AM\",\
\"astronomical_twilight_end\":\"6:38:43 PM\"\
},\
\"status\":\"OK\"\
}";

您可以使用string.h中的strtok功能轻松处理它。首先使用{,分隔符将"result":{"sunrise ...分开。然后,您可以使用},分隔符。

使用strstr,您可以检查"sunrise""sunset"字段,如果找到它们,则可以将其值复制到strncpy的新字符串中。

int main()
{
    char* field;
    char* sunset;
    char* sunrise;

    field = strtok(response,"{,");

    while (field != NULL)
    {
        field = strtok (NULL, ",}");

        if(field != NULL)
        {
            if(strstr(field, "sunrise") != NULL)
            {
                int length = strlen(field);
                sunrise = malloc(length * sizeof(char) + 1); // +1 for terminating null character '\0'
                strncpy(sunrise, field, length + 1);         // +1 to copy a terminating null as well
            }

            if(strstr(field, "sunset") != NULL)
            {
                int length = strlen(field);
                sunset = malloc(length * sizeof(char) + 1); // +1 for terminating null character '\0'
                strncpy(sunset, field, length + 1);         // +1 to copy a terminating null as well
            }
        }
    }

    printf("SUNRISE DATA: %s\n\n", sunrise);
    printf("SUNSET  DATA: %s\n\n", sunset);

    free(sunrise);  // do not forget to free the memory if not needed anymore
    free(sunset);   // do not forget to free the memory if not needed anymore

    return 0;
}

该程序的输出是:

SUNRISE DATA: "sunrise":"7:27:02 AM"

SUNSET  DATA: "sunset":"5:05:55 PM"

如果您愿意,可以再次使用strtok进一步处理这些字符串。这只是一个示例代码,您可以使用它来实现您的解决方案。