Reputation: 17
I cannot connect to Wi-fi on my ESP32 DEV-KIT; I have a String
which contains ssid and password, but the WIFI.begin()
function accepts only const char*
, and I don't know how to convert String
to const char*
. I have tried the c_str()
function, but the result I am getting is != (not equal) to the actual ssid.
String ssid = "DIR-615A";
char ssidR;
const char* ssidR2 = "DIR-615A";
void setup() {
ssidR = ssid.c_str();
Serial.println(ssidR);
Serial.println(ssidR2);
Serial.println(ssidR == ssidR2); //this returns 0
}
Both ssidR and ssidR2 look identical when printing them, but when I use ssidR to connect to wi-fi, it is not working.
Upvotes: 1
Views: 3866
Reputation: 536
I was going to try to put this as a comment, but it's unwieldy there. It's kind of screwed up as an answer, because your question seems to be predicated on an misunderstandings of what to expect from ==
and const char *
and what can be done with a single char
, but it does at least address what's been said.
/*char*/ ssidR = ssid.c_str();
and ssidR == ssidR2
I addressed this part in a comment, but since as though I'm making an answer now I'll pull it into here. I'm not repeating this just to beat a dead horse.
You are attempting to assign a pointer to const char
to a single char
. Basically you're trying to cram 32bit (in this case) address of something into a character and then you're trying to compare that with const char *
again:
Serial.println(ssidR == ssidR2); //this returns 0
Right, it would do. Without splitting hairs about the language standard and undefined behaviour on overflow, etc. what you're doing here is comparing the low byte of the address of the buffer maintained by your String
object with the full address of your string literal "DIR-615A"
and they're not equal.
begin()
and const char *
From your comment on the question
i dont know why the guy who wrote th elibrary decided to make it accept only char pointers.
An entire answer could be written on the decision to just support const char *
; There are reasons, though some maybe relevant more historically and may persist more out of habit than anything else. If you want an example of that sort of thing you can look at open()
for fstream
in C++ prior to C++17; it accepted const char *
but not std::string
which is standard C++'s counterpart to the Arduino String
type.
The main thing I'd impress on you is that it accepting const char *
is not actually a problem for you at all. There's absolutely nothing wrong with calling begin
with ssid.c_str()
and your WiFi connectivity problems don't have anything to do with their decision.
==
on pointers compares the pointers themselves and not the things being pointed-to. In the case of const char *
, the compiler couldn't generally know what to compare once it followed the pointer; at the time ==
is evaluated the compiler can't reliable know that these pointers point at null terminated strings and not some other sequence of zero or more chars.
The C and C++ languages allow for string literals to be overlapped in memory, that is to not have distinct addresses, which can lead you to the false sense that you've used ==
in a way that it's actually comparing the strings. "yes" == "yes"
will usually evaluate to true, because typical compilers will reuse the first instance of the literal for the second, and so they're in the same memory location, so ==
appears to work when it in fact didn't. There's no requirement that the reuse the same memory. And in this case: char no[3] = "no"; if (no == "no") {
will be false. Because the no
char array is a distinct object, nothing else has its address, including a string literal you might try to compare it to which has the same contents.
What you seem to want to do to convince yourself that .c_str()
yields what you want can be done in a pile of ways. The traditional way (from C) to compare null-terminated c-strings is with the strcmp
function:
String ssid_via_str_obj = "DIR-615A";
const char *ssid_via_char_ptr = "DIR-615A";
// ...
if (strcmp(ssid_via_str_obj.c_str(), ssid_via_char_ptr) == 0) {
// note strcmp returns zero for equality,
// numbers above and below zero are used to represent greater and lessor.
Serial.println("Equal");
} else {
Serial.println("Unequal");
}
There's also an endless pile of ways you could do this with the Arduino String
, and c++ std::string
and std::string_view
classes you have available to you.
Upvotes: 2
Reputation: 2270
You can use toCharArray() to convert the String object into an array of char
s.
Also, you have to use strcmp()
to compare two strings, otherwise you're literally just comparing the address in memory where the data is kept.
To use it:
char ssid_char[100]; /* or however long your SSID is going to be */
ssid.toCharArray(ssid_char, ssid.length());
wifi.begin(ssid_char);
The reason is that you need space to store the content of the string somewhere. Your ssidR
variable was just a pointer to memory, but there was no memory to store the actual string. By using a static array, the memory is reserved for the toCharArray()
call to fill.
Upvotes: 2