Arduino 简明教程

Arduino - Strings

字符串用于存储文本。它们可用于在 LCD 上或 Arduino IDE 串行监视器窗口中显示文本。字符串对于存储用户输入也很有用。例如,用户在连接到 Arduino 的键盘上键入的字符。

在 Arduino 编程中有两种类型的字符串 -

  1. 字符数组,这与 C 编程中使用的字符串相同。

  2. Arduino String,它允许我们在草图中使用字符串对象。

在本章中,我们将学习字符串、对象以及字符串在 Arduino 草图中的用法。在本节末尾,你将学习在草图中使用哪种类型的字符串。

String Character Arrays

我们将学习的第一种类型的字符串是一系列 char 类型的字符。在上一章中,我们学习了数组是什么;一系列连续的同类型变量,存储在内存中。字符串是 char 变量的数组。

字符串是一个特殊的数组,其在字符串末尾有一个额外的元素,该元素的值始终为 0(零)。这被称为“空终止字符串”。

String Character Array Example

此示例将展示如何制作字符串并将其打印到串行监视器窗口。

Example

void setup() {
   char my_str[6]; // an array big enough for a 5 character string
   Serial.begin(9600);
   my_str[0] = 'H'; // the string consists of 5 characters
   my_str[1] = 'e';
   my_str[2] = 'l';
   my_str[3] = 'l';
   my_str[4] = 'o';
   my_str[5] = 0; // 6th array element is a null terminator
   Serial.println(my_str);
}

void loop() {

}

以下示例显示了字符串的构成;一个字符数组,其中包含可打印字符,并且 0 为数组的最后一个元素,以表明这是字符串的结束位置。可以使用 Serial.println() 并传递字符串的名称将字符串打印到 Arduino IDE 串行监视器窗口。

可以使用以下更简洁的方式编写此示例 -

Example

void setup() {
   char my_str[] = "Hello";
   Serial.begin(9600);
   Serial.println(my_str);
}

void loop() {

}

在此草图中,编译器计算字符串数组的大小,并使用零自动空终止字符串。与上一草图完全相同的方式创建了一个由六个元素组成且包含五个字符后跟一个零的数组。

Manipulating String Arrays

我们可以在草图中更改字符串数组,如下面的草图所示。

Example

void setup() {
   char like[] = "I like coffee and cake"; // create a string
   Serial.begin(9600);
   // (1) print the string
   Serial.println(like);
   // (2) delete part of the string
   like[13] = 0;
   Serial.println(like);
   // (3) substitute a word into the string
   like[13] = ' '; // replace the null terminator with a space
   like[18] = 't'; // insert the new word
   like[19] = 'e';
   like[20] = 'a';
   like[21] = 0; // terminate the string
   Serial.println(like);
}

void loop() {

}

Result

I like coffee and cake
I like coffee
I like coffee and tea

草图按以下方式工作。

Creating and Printing the String

在上面给出的草图中,创建了一个新字符串,然后打印出来在串行监视器窗口中显示。

Shortening the String

字符串通过将字符串中的第 14 个字符替换为空终止零 (2) 来缩短。这是元素编号 13,从 0 开始计算字符串数组。

当打印字符串时,所有字符都会打印到新的空终止零。其他字符不会消失,它们仍存在于内存中,字符串数组的大小保持不变。唯一的区别是任何使用字符串的函数都只会看到字符串直到第一个空终止符。

Changing a Word in the String

最后,草图将单词“cake”替换为“tea”(3)。它必须首先用空格替换 like[13] 处的空终止符,以便将字符串还原为最初创建的格式。

新字符用单词“tea”覆盖单词“cake”的“cak”。这是通过覆盖单个字符来完成的。“cake”的’e’被替换为一个新的空终止符。结果是字符串实际上以两个空字符结尾,第一个空字符位于字符串末尾,另一个空字符替换了“cake”中的’e'。当打印新字符串时,这没有任何区别,因为打印字符串的函数在遇到第一个空终止符时会停止打印字符串字符。

Functions to Manipulate String Arrays

前一节草图通过访问字符串中的单个字符来以一种手动的方式操纵字符串。要使其更容易操纵字符串数组,你可以编写你自己的函数来操作它们,或使用来自 C 语言库的部分字符串函数。

下一节草图使用了部分 C 字符串函数。

Example

void setup() {
   char str[] = "This is my string"; // create a string
   char out_str[40]; // output from string functions placed here
   int num; // general purpose integer
   Serial.begin(9600);

   // (1) print the string
   Serial.println(str);

   // (2) get the length of the string (excludes null terminator)
   num = strlen(str);
   Serial.print("String length is: ");
   Serial.println(num);

   // (3) get the length of the array (includes null terminator)
   num = sizeof(str); // sizeof() is not a C string function
   Serial.print("Size of the array: ");
   Serial.println(num);

   // (4) copy a string
   strcpy(out_str, str);
   Serial.println(out_str);

   // (5) add a string to the end of a string (append)
   strcat(out_str, " sketch.");
   Serial.println(out_str);
   num = strlen(out_str);
   Serial.print("String length is: ");
   Serial.println(num);
   num = sizeof(out_str);
   Serial.print("Size of the array out_str[]: ");
   Serial.println(num);
}

void loop() {

}

Result

This is my string
String length is: 17
Size of the array: 18
This is my string
This is my string sketch.
String length is: 25
Size of the array out_str[]: 40

草图按以下方式工作。

Print the String

新创建的字符串被打印到 Serial Monitor 窗口,正如在之前的草图中所做的一样。

Get the Length of the String

strlen() 函数用于获取字符串的长度。字符串的长度仅限于可打印字符,且不包含空终止符。

该字符串包含 17 个字符,所以我们将在 Serial Monitor 窗口中看到打印的 17。

Get the Length of the Array

sizeof() 运算符用于获取包含字符串的数组的长度。该长度包含空终止符,所以该长度比字符串长度多 1。

sizeof() 看起来像一个函数,但实际上它是一个运算符。它不是 C 字符串库的一部分,但在草图中使用了它来展示数组的大小和字符串的大小(或字符串长度)之间的差异。

Copy a String

strcpy() 函数用于将 str[] 字符串复制到 out_num[] 数组中。strcpy() 函数将传递给它的第二个字符串复制到第一个字符串中。该 out_num[] 数组中现在存在着该字符串的副本,但只占用该数组的 18 个元素,所以该数组中仍有 22 个空 char 元素。这些空元素在内存中字符串之后被找到。

该字符串之所以被复制到该数组中,是因为我们想在该数组中拥有额外的空间用于草图的下一部分,即在字符串末尾添加一个字符串。

Append a String to a String (Concatenate)

该草图将一个字符串与另一个字符串相连接,这被称为连接。这是使用 strcat() 函数来完成的。strcat() 函数将传递给它的第二个字符串放置在传递给它的第一个字符串的末尾。

在连接后,将打印出该字符串的长度以展示新的字符串长度。然后打印出该数组的长度以展示我们在一个 40 个元素长的数组中有 25 个字符长的字符串。

记住,该 25 个字符长的字符串实际上占用了该数组的 26 个字符,因为空终止零。

Array Bounds

当使用字符串和数组时,在字符串或数组的范围内工作非常重要。在示例草图中,创建了一个 40 个字符长的数组,为了分配可以用以操纵字符串的内存。

如果该数组变得过小,而我们试图复制一个比该数组更大的字符串到该数组中,那么该字符串将被复制到该数组的末尾。该数组末尾之外的内存可能包含草图中用到的其他重要数据,而后者将被我们的字符串覆盖。如果该字符串末尾之外的内存被覆写,则可能导致草图崩溃或造成意外的行为。