3

我正在编写一个 arduino 库来在网络上发布 http 请求。

我正在使用来自http://arduino.cc/en/Tutorial/TextString的 String 类

当我在函数调用后引用我定义的字符串对象时,我的代码表现得很奇怪。

这里实际上我正在尝试获取我的 GET 请求的正文并从 http GET 请求的响应中删除 http 标头。

以下是说明:

方法调用:

  String body;  
  if(pinger.Get(host,path,&body))
  {
    Serial.println("Modified String Outside :");
    Serial.println(body);
    Serial.println();
    Serial.println("Modified String Outside Address");
    Serial.println((int)&body);
  }

输出

Modified String Outside :
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 113
Date: Wed, 13 Jan 2010 14:36:28 GMT

<html>
<head>
<title>Ashish Sharma
</title>
</head>
<body>
Wed Jan 13 20:06:28 IST 2010
</body>
</html>


Modified String Outside Address
2273

方法说明:

bool Pinger::Get(String host, String path, String *response) {
    bool connection = false;
    bool status = false;

    String post1 = "GET ";
    post1 = post1.append(path);
    post1 = post1.append(" HTTP/1.1");

    String host1 = "Host: ";
    host1 = host1.append(host);

    for (int i = 0; i < 10; i++) {
        if (client.connect()) {
            client.println(post1);
            client.println(host1);
            client.println();
            connection = true;
            break;
        }
    }

    int nlCnt = 0;
    while (connection) {
        if (client.available()) {
            int c = client.read();
            response->append((char) c);
            if (c == 0x000A && nlCnt == 0) {
                nlCnt++;
                if (response->contains("200")) {
                        status = true;
                        continue;
                    } else {
                        client.stop();
                        client.flush();
                        break;
                    }   
            }
        }
        if (!client.connected()) {
            client.stop();
            connection = false;
        }
    }           
    response = &response->substring(response->indexOf("\n\r\n"),response->length());    
    Serial.println("Modified String: ");
    Serial.println(*response);  

    Serial.println();
    Serial.print("Modified String Address: ");
    Serial.println((int)&response);
    return status;
}

输出:

Modified String: 
Ø
<html>
<head>
<title>Ashish Sharma
</title>
</head>
<body>
Wed Jan 13 20:06:28 IST 2010
</body>
</html>

Modified String Address: 2259

从示例中可以看出,字符串引用对象在 Get 方法中为我提供了正确的字符串,但是当 Get 方法返回时,字符串内容的引用发生了变化。

4

3 回答 3

3

首先,您正在修改字符串的地址,而不是字符串本身。但是字符串的地址是通过value传递给函数的,因此被复制了。在函数内部修改它不会在外部修改它。

其次,这里的代码很糟糕:

response = &response->substring(response->indexOf("\n\r\n"),response->length());

因为它创建了一个指向临时对象的指针——这意味着:一个悬空指针,因为临时对象将在表达式被计算后被销毁。

真正想要的是通过引用(String& response)传递对象并修改它,而不是它的指针:

response = response->substring(response->indexOf("\n\r\n"),response->length());

如果您正确使用的String类重载了赋值运算符的行为,这应该可以工作=

于 2010-01-13T15:09:18.380 回答
3

如果我正确理解了您的代码,您可能会想要执行以下操作:

*response = response->substring(response->indexOf("\n\r\n"),response->length());

代替

response = &response->substring(response->indexOf("\n\r\n"),response->length());

此外,可能不需要传入指针(引用可能会使代码看起来更好)。

于 2010-01-13T15:16:48.147 回答
1

线

 Serial.println((int)&response);

在你的函数里面是错误的响应已经是一个指针(String * response),用&response你得到指向指针的指针。
将其更改为

Serial.println((int)response);

你应该得到与

 Serial.println((int)&body);

其中 body 是字符串,&body 是指向字符串的指针

于 2010-01-13T15:45:52.987 回答