3

httpリクエストをWebに投稿するarduinoライブラリを作成しています。

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

私があなたのコードを正しく理解していれば、おそらく次のようなことをしたいと思うでしょう:

*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 に答える
3

まず、文字列自体ではなく、文字列のアドレスを変更しています。しかし、文字列のアドレスは値によって関数に渡されたため、コピーされました。関数内で変更しても、外側では変更されません。

第二に、このコードは悪いです:

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 に答える
1

この線

 Serial.println((int)&response);

あなたの関数の内部では、応答はすでにポインター (文字列 * 応答) であり、 &response を使用すると、ポインターへのポインターを取得できます。
に変更します

Serial.println((int)response);

と同じアドレスを取得する必要があります

 Serial.println((int)&body);

ここで、body は文字列で、&body は文字列へのポインタです

于 2010-01-13T15:45:52.987 に答える