使用Arduino字符串功能

您想要操作文本。您需要复制它,将其拼接在一起,并确定字符数。

解决方案:

前面的示例提到,字符数组可以用于存储文本:这些字符数组通常称为字符串。Arduino具有一个String对象,可以添加丰富的功能来存储和操作文本。请注意,String对象名称中的“S”是大写的。



大写字母S的String指的是由Arduino String库提供的Arduino文本功能。小写字母s的string指的是字符组,而不是Arduino String功能。

本示例演示如何使用Arduino Strings。将以下代码加载到您的板子上,并打开串行监视器以查看结果:

C++Copy code/*
 Basic_Strings sketch
 */
String text1 = "This text";
String text2 = " has more characters";
String text3; // 将在代码块内进行赋值
void setup()
{
   Serial.begin(9600);
   while(!Serial); // 等待串口(Leonardo,32位板)
   Serial.print("text1 is ");
   Serial.print(text1.length());
   Serial.println(" characters long.");
   Serial.print("text2 is ");
   Serial.print(text2.length());
   Serial.println(" characters long.");
   text1.concat(text2);
   Serial.println("text1 now contains: ");
   Serial.println(text1);
}
void loop()
{
}

为什么不使用Serial?

对于Arduino Uno和大多数8位板,当您在Arduino IDE中打开串行监视器时,它会重置板子,这意味着您会在打开串行监视器后不久看到任何生成的串行输出。然而,在Leonardo和基于SAMD的板上,打开串行端口不会自动重置板子,这意味着您可能无法快速打开串行监视器以捕获输出。因此,在本章和整本书中,您会看到几个setup函数中的while(!Serial);行。

此示例创建了三个名为text1、text2和text3的String类型变量。String类型变量具有内置的文本操作功能。语句text1.length()返回字符串text1中字符的长度(数量)。

text1.concat(text2)将字符串内容组合在一起;在本例中,它将text2的内容附加到text1的末尾(concat是concatenate的缩写)。

串行监视器将显示以下内容: text1长度为9个字符。 text2长度为20个字符。 text1现在包含: This text has more characters 另一种组合字符串的方法是使用字符串加法运算符。将以下两行代码添加到设置代码的末尾: text3 = text1 + " and more"; Serial.println(text3); 新代码将导致串行监视器将以下行添加到显示的末尾: This text has more characters and more 您可以使用indexOf和lastIndexOf函数在字符串中查找特定字符的实例。与数组一样,Arduino字符串以0开始索引。

你会遇到使用字符数组或指向一系列字符的指针而不是String类型的Arduino代码。请参阅第2.6节以了解如何在没有Arduino String功能的情况下使用字符数组。请参阅第17.4节,以了解将字符串文字存储在闪存中而不是Arduino的主要工作RAM存储器中的说明。

如果你看到以下一行代码:

char oldString[] = "this is a character array";

代码使用了C风格的字符数组(见第2.6节)。如果声明看起来像这样:

String newString = "this is a string object";

则代码使用Arduino Strings。要将C风格的字符数组转换为Arduino String,只需将数组的内容分配给String对象即可:

char oldString[] = "I want this character array in a String object";

String newString = oldString;

要使用Table 2-4中列出的任何函数,需要将它们调用现有的字符串对象,如此示例所示:

int len = myString.length();


表格2-4。Arduino字符串函数简要概述

函数

作用

charAt(n)

返回字符串中的第n个字符

compareTo(S2)

将字符串与给定的字符串S2进行比较

concat(S2)

返回一个新的字符串,是字符串和S2的组合

endsWith(S2)

如果字符串以S2的字符结尾,则返回true

equals(S2)

如果字符串与S2完全匹配(区分大小写),则返回true

equalsIgnoreCase(S2)

与equals相同,但不区分大小写

getBytes(buffer,len)

将len个字符复制到提供的字节缓冲区中

indexOf(S)

返回提供的字符串(或字符)的索引,如果未找到则返回-1

lastIndexOf(S)

与indexOf相同,但从字符串的末尾开始搜索

length()

返回字符串中的字符数

remove(index)

删除给定索引处的字符串字符

remove(index, count)

从给定索引处开始删除指定数量的字符串字符

replace(A,B)

将所有的字符串(或字符)A替换为B

reserve(count)

分配指定数量的字节以使后续字符串操作更加高效

setCharAt(index,c)

在给定的索引处将字符c存储在字符串中

startsWith(S2)

如果字符串以S2的字符开头,则返回true

substring(index)

返回从索引开始到字符串末尾的字符串字符

substring(index,to)

与上述相同,但子字符串在to位置之前结束

toCharArray(buffer,len)

将字符串中的最多len个字符复制到提供的缓冲区中

toFloat()

返回字符串中数字字符的浮点值

toInt()

返回字符串中数字字符的整数值

toLowerCase()

返回所有字符转换为小写的字符串

toUpperCase()

返回所有字符转换为大写的字符串

trim()

返回删除所有前导和尾随空格的字符串

请参阅Arduino参考页面,以了解有关这些函数的用法和变体的更多信息。


在Arduino中选择使用String数据类型还是C字符数组 Arduino内置的String数据类型比C字符数组更易于使用,但是这是通过String库中的复杂代码实现的,这使得Arduino对您的要求更高,并且因其本质而更容易出现问题。 String数据类型非常灵活,因为它利用动态内存分配。也就是说,当您创建或修改字符串时,Arduino会从C库请求新的内存区域,并且在您使用字符串完成后,Arduino需要释放该内存。这通常可以顺利进行,但是8位Arduino板具有非常少的工作RAM(Arduino Uno上为2K),即使是小内存泄漏也可能对您的草图产生重大影响。内存泄漏是指通过库中的错误或不正确的使用而未释放您分配的内存。当发生这种情况时,Arduino可用的内存将缓慢减少(直到您重新启动Arduino)。

相关问题是内存碎片化:随着您重复分配和释放内存,Arduino将具有连续的自由内存块越来越小,即使有足够的RAM,这也可能导致String分配失败。 即使没有内存泄漏,编写代码检查由于内存不足而导致String请求失败也很复杂(String函数模仿Processing中的函数,但与该平台不同,Arduino没有运行时错误异常处理)。动态内存不足是一个很难追踪的错误,因为草图可能在几天或几周内没有问题运行,然后由于内存不足而开始出现问题。 如果您使用C字符数组,则可以控制内存使用情况:在编译时分配固定(静态)数量的内存,因此您不会出现内存泄漏。您的Arduino草图将始终拥有相同数量的可用内存。如果尝试分配超过可用内存的内存,则可以更容易地找到原因,因为有工具可以告诉您已分配了多少静态内存。

然而,使用 C 字符数组会让你更容易出现另一个问题:C 无法阻止你修改数组范围之外的内存。因此,如果你分配一个 myString[4] 的数组,并赋值 myString[4] = 'A'(请记住,myString[3] 是数组的结尾),没有任何东西会阻止你这样做。但是,谁知道 myString[4] 引用哪块内存?谁知道给该内存位置分配 'A' 是否会给你造成问题?最有可能的是,这会导致你的程序行为异常。 因此,Arduino 内置的 String 库通过使用动态内存的方式,存在耗尽可用内存的风险。C 的字符数组需要你小心谨慎地确保不会超出所使用数组的范围。

因此,如果你需要具备丰富的文本处理功能,并且不需要反复创建和修改字符串,可以使用 Arduino 内置的 String 库。如果你需要在不断重复的循环中创建和修改字符串,则最好分配一个大的 C 字符数组,并仔细编写代码,以避免超出该数组的范围。 另一个你可能更喜欢使用 C 字符数组而不是 Arduino String 的情况是在需要大部分可用 RAM 或 flash 的大型程序中。Arduino 的 StringToInt 示例代码比使用 C 字符数组和 atoi 转换为 int 的代码多使用了将近 2KB 的 flash。Arduino String 版本还需要一些 RAM 来存储分配信息以及实际字符串。

我们还可以使用strtol()函数将字符串转换成整数以节省ArduinoRAM开销,如下示例:

void setup() {
  Serial.begin(9600);  // 初始化串口通信
  char num_str[] = "1234";  // 定义字符串
  char *end_ptr;  // 定义指向转换后剩余部分的指针
  long num = strtol(num_str, &end_ptr, 10);  // 将字符串转换为十进制长整数
  if (*end_ptr != '') {
    Serial.println("转换错误。");
  } else {
    Serial.println(num);  // 打印长整数
  }
}

void loop() {
  // do nothing
}
展开阅读全文

页面更新:2024-02-18

标签:字符串   末尾   监视器   数组   示例   函数   字符   分配   内存   代码   功能

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top