我的 ESP32 DEV-KIT 无法连接到 Wi-fi;我有一个包含 ssid 和密码的 String
,但 WIFI.begin()
函数只接受 const char*
,我不知道如何将 String
转换为 const char*
.我已经尝试了 c_str()
函数,但我得到的结果是 !=(不等于)实际的 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
}
ssidR 和 ssidR2 在打印时看起来都一样,但是当我使用 ssidR 连接到 wi-fi 时,它不起作用。
答案 0 :(得分:2)
您可以使用 toCharArray() 将 String 对象转换为 char
的数组。
此外,您必须使用 strcmp()
来比较两个字符串,否则您实际上只是在比较保存数据的内存中的地址。
使用:
char ssid_char[100]; /* or however long your SSID is going to be */
ssid.toCharArray(ssid_char, ssid.length());
wifi.begin(ssid_char);
原因是您需要空间来将字符串的内容存储在某处。您的 ssidR
变量只是一个指向内存的指针,但没有存储实际字符串的内存。通过使用静态数组,内存被保留用于 toCharArray()
调用来填充。
答案 1 :(得分:1)
我本想把它作为评论,但它在那里很笨拙。作为答案有点搞砸了,因为您的问题似乎是基于对 ==
和 const char *
的期望以及单个 char
可以做什么的误解,但是它至少解决了人们所说的问题。
/*char*/ ssidR = ssid.c_str();
和ssidR == ssidR2
我在评论中谈到了这一部分,但既然我现在正在回答,我就把它放到这里。我不是为了打败一匹死马而重复这个。
您正试图将指向 const char
的指针分配给单个 char
。基本上,您试图将某些内容的 32 位(在本例中)地址塞入一个字符中,然后再次尝试将其与 const char *
进行比较:
Serial.println(ssidR == ssidR2); //this returns 0
好的,可以的。没有关于语言标准和溢出等未定义行为的分歧,你在这里所做的是将 String
对象维护的缓冲区地址的低字节与字符串文字的完整地址进行比较 "DIR-615A"
{1}} 并且它们不相等。
begin()
和 const char *
来自你对问题的评论
<块引用>我不知道为什么编写 elibrary 的人决定让它只接受字符指针。
关于只支持const char *
的决定,可以写出完整的答案;有一些原因,尽管有些可能与历史更相关,并且可能比其他任何事情都更出于习惯而坚持下去。如果您想要此类示例,您可以在 C++17 之前的 C++ 中查看 open()
for fstream
;它接受 const char *
但不接受 std::string
,后者是标准 C++ 对 Arduino String
类型的对应物。
我给您留下深刻印象的主要内容是它接受 const char *
实际上对您来说根本不是问题。用 begin
调用 ssid.c_str()
绝对没有错,您的 WiFi 连接问题与他们的决定没有任何关系。
==
在指针上比较指针本身而不是被指向的东西。在 const char *
的情况下,一旦跟随指针,编译器通常不知道要比较什么;在计算 ==
时,编译器无法可靠地知道这些指针指向空终止字符串,而不是其他零个或多个字符序列。
C 和 C++ 语言允许字符串字面量在内存中重叠,即没有不同的地址,这可能会导致您误以为您使用 ==
的方式实际上是比较字符串。 "yes" == "yes"
通常会评估为真,因为典型的编译器会重用文字的第一个实例作为第二个实例,因此它们位于相同的内存位置,因此 ==
实际上似乎可以工作没有。没有要求重用相同的内存。在这种情况下:char no[3] = "no"; if (no == "no") {
将是假的。因为 no
字符数组是一个不同的对象,所以没有其他对象有它的地址,包括您可能尝试将其与内容相同的字符串文字进行比较。
您似乎想要说服自己 .c_str()
产生您想要的东西的方法可以通过多种方式完成。比较以空字符结尾的 c 字符串的传统方法(来自 C)是使用 strcmp
函数:
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");
}
您还可以使用 Arduino String
和 C++ std::string
和 std::string_view
类来实现此目的的方法数不胜数。