So in the code below I get the error
error: 'mystr' was not declared in this scope
mystr +=c;
If I run the code is another IDE ( platoformIO ) I get
no suitable user-defined conversion from "String" to "std::__cxx11::string" (aka "std::__cxx11::basic_string<char, std::char_traits, std::allocator>") existsC/C++(312)
Basically I'm tring to convert String to string without success. So if anyone can help with this it would be MASSIVELY appreciated. Have tried many google searches but can't figure out how to do it, maybe it's not even possible
#include <WiFi.h>
#include <WebServer.h>
#include <ArduinoJson.h>
#include <string.h>
#include <fastled_config.h>
#include <iostream>
void setup() {
handleMorse();
}
void loop() {
// put your main code here, to run repeatedly:
}
void handleMorse() {
String message = "my test message";
Serial.println( message );
string mystr = ""; // note this is string & NOT String
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
mystr +=c; // error here
if (i< 8)
Serial.print (c);
}
Serial.print (mystr); // error
}
The reason I'm using string & String is because I'm receiving code from a app which comes in as a String but I've written code in visual studio which takes a string & I didn't actually realise at the time that they were 2 different types ( easy mistake for a noob like me ).
Yes to both - Im copying code to arduinoIDE from what i've written in visual studio ( easier because of intellisense & being able to output results to a console for debugging ). I am also receiving data from a app over wifi using http_post ( from app).
WebServer server(80);
// in setup
server.on("/morse", HTTP_POST, handleMorse);
void handleMorse() {
String message = server.arg("message");
Serial.println("Received message: " + message);
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
if (i< 8)
Serial.print (c);
}
}
not sure what this is saying, don't understand why a string is being passed as an argument to a function returning a string. Is the returned value "message"
i'm sure you can receive char array strings from via Wifi
you'll find this as functions of the class WebServer:
String arg(const String &name) const; // get request argument value by name
String arg(int i) const; // get request argument value by number
String argName(int i) const;
Assuming that the TO is using this library it explains the use of the String class.
The reason for using a String object to get another one in return is this:
String WebServer::arg(const String &name) const {
for (int j = 0; j < _postArgsLen; ++j) {
if (_postArgs[j].key == name) {
return _postArgs[j].value;
}
}
for (int i = 0; i < _currentArgCount; ++i) {
if (_currentArgs[i].key == name) {
return _currentArgs[i].value;
}
}
return "";
}
The arg functions iterates through an array similar to "JSON" where _postArgs points to structs of type RequestArgument
I use it the same way.
if the argument to the function is
"message"
then the function returns
?message=thismessage
"thismessage"
Usually one would do all the parsing before the new webpage is being created but some precautions with regards to possible fragmentation should be observed.
If you store the returned String in a String then it is probably a good idea to reserve() sufficient space for it.
Still this is all happening in the callback and once the callback function is exited all String objects are destroyed and all memory will be released.
server.arg() is returning a String object by value. So, it will be a temporary, and hence an rvalue. So, this will invoke the String class's move constructor:
So there will not be another buffer allocated for the local String variable anyway. Rather it will take over the rvalue's buffer.
Yes that is true, but since the passed argument is created beforehand, the returned String will be created further along the heap. in this scenario
String outputString = "The returned value of the HTML Argument is : ";
outputString += server.arg("message");
The object 'outputString' will be moved because there is not enough space in the original location to create the concatenated String, because both the temporary "message" as well as the return String are created after the original String. As far as i know there is no real way to prevent that fragmentation unless there is sufficient space in the String.
If all the date from the return String is discarded before anything is added to the original String there may be no problem, and even if the String is kept in tact and used for instance in a filename or something and then used it is also Ok. (in my case that is what usually happens, most of the HTML arguments are numeric values and get converted before processing)
Another option could be to convert the return String to a c-string and let the returned String go out of scope before adding it to outputString, or allocate space beforehand.