构建字符串(或字符)数组 - 新手

物联网 ESP32
2021-06-15 17:54:53

我对此很陌生,并且只做了几个星期。虽然我已经用其他语言编程过,但我对声明类型、转换类型和指针的理解仍然很短。我昨天一整天都在尝试让这段代码正常工作,但不能!

我需要一个数组(字符或字符串)来保存锁定信息,然后能够将它作为字符串传递给电子邮件函数。如果我让一个部分工作,它会破坏下一部分。当前版本的代码如下所示:

char lockDetail [10][250];

String ts =  timeStamp();
char reason [] = "Invalid login attemp " + ts + "other stuff I want to append";
strncpy(lockDetail [lockCount], reason, sizeof(reason) );
.
.
.
String msg = lockDetail [0] + "<p>" + lockDetail [1] + "<p>" + lockDetail [2];
sendMessage (subject, msg);

我按照 jcaron 的建议更新了我的代码,现在我遇到了与最初相同的问题 - 调用它时会崩溃/重新启动 ESP32。

更新代码:

String lockDetail [2];
int lockCount = 0;
String ts =  timeStamp();
String reason = "Invalid login attemp " + ts + "other stuff I want to append";
lockDetail[lockCount] = String(reason);
.
.
String msg = lockDetail [0] + "<p>" + lockDetail [1] + "<p>" + lockDetail [2];

在进一步调查中,当我调用带有 msg = 到 msg 的 sendMessage 函数时发生崩溃,其中包括 lockDetail 数组。我正在使用mobizt/ESP-Mail-Client 库

void sendMessage(const char* subject, String msg)

所以崩溃: String msg = lockDetail [0] + "<p>" + lockDetail [1] + "<p>" + lockDetail [2];

没有崩溃: sendMessage ("subject", "My Message");

不确定这是否有帮助(它高于我目前的水平)。这是来自邮件库示例(也在我的代码中使用)。想知道 .c_str() 部分是否有数组问题(但现在我们创建的不是 msg 只是一个普通的普通字符串?)

String msg = "the message"; 
message.html.content = msg.c_str();

更多帮助表示赞赏,谢谢

2个回答

主要问题是您正在混合 C 样式字符串(字符数组)和 C++ 样式字符串(对象),这会产生奇怪的结果。

在 Arduino 环境中,除非您知道自己在做什么,否则您可能希望使用 C++ 风格的String对象而不是 C 风格的char[]字符串。

char lockDetail [10][250];

您正在定义一个 2D 数组(它也有固定的大小,这可能会引发许多问题)。相反,定义一个String对象数组

String lockDetail[10];
char reason [] = "Invalid login attemp " + ts + "other stuff I want to append";

您正在通过连接几个字符串对象来创建一个字符串对象,然后尝试将其分配给一个 C 风格的字符串(不起作用),它还需要一个静态初始化程序,以便可以计算字符串的大小(在至少ts不是恒定的,不会起作用)。相反,创建一个String对象:

String reason = "Invalid login attemp " + ts + "other stuff I want to append";
strncpy(lockDetail [lockCount], reason, sizeof(reason) );

您正在将一个 C 风格的字符串复制到另一个中。请注意,即使sizeof(reason)具有正确的值,它也不是您应该使用的值strncpy:您应该使用目标缓冲区的大小,而不是源缓冲区的大小(源字符串的长度由终止的 nul 定义)。

但是由于我们切换到字符串对象(您不能strncpy在其上使用),让我们只制作一个副本(请注意,根据您的实际代码,它甚至可能不需要制作副本):

lockDetail[lockCount] = String(reason);
String msg = lockDetail [0] + "<p>" + lockDetail [1] + "<p>" + lockDetail [2];

这是行不通的,因为lockDetail[0]是一个 C 风格的字符串(实际上是 a char [250]),"<p>"在这种情况下是另一个 C 风格的字符串(实际上是 a const char [4]),其余部分同上。你不能添加那些。但是现在我们已经将每个人都切换到String对象,它会起作用。

我想到了。我正在将电子邮件消息传递给数组的最后一个元素,该元素为空。这就是导致崩溃的原因。