ESP32 使用 String ssid 连接到 Wi-fi

时间:2021-06-22 09:54:26

标签: c++ arduino wifi esp32

我的 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 时,它不起作用。

2 个答案:

答案 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 连接问题与他们的决定没有任何关系。

NOT 比较 c 字符串

== 在指针上比较指针本身而不是被指向的东西。在 const char * 的情况下,一旦跟随指针,编译器通常不知道要比较什么;在计算 == 时,编译器无法可靠地知道这些指针指向空终止字符串,而不是其他零个或多个字符序列。

C 和 C++ 语言允许字符串字面量在内存中重叠,即没有不同的地址,这可能会导致您误以为您使用 == 的方式实际上是比较字符串。 "yes" == "yes" 通常会评估为真,因为典型的编译器会重用文字的第一个实例作为第二个实例,因此它们位于相同的内存位置,因此 == 实际上似乎可以工作没有。没有要求重用相同的内存。在这种情况下:char no[3] = "no"; if (no == "no") { 将是假的。因为 no 字符数组是一个不同的对象,所以没有其他对象有它的地址,包括您可能尝试将其与内容相同的字符串文字进行比较。

比较 c 字符串

您似乎想要说服自己 .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::stringstd::string_view 类来实现此目的的方法数不胜数。

相关问题