Arduino - Chuỗi

Chuỗi được sử dụng để lưu trữ văn bản. Chúng có thể được sử dụng để hiển thị văn bản trên màn hình LCD hoặc trong cửa sổ Arduino IDE Serial Monitor. Chuỗi cũng hữu ích để lưu trữ dữ liệu đầu vào của người dùng. Ví dụ: các ký tự mà người dùng nhập trên bàn phím được kết nối với Arduino.

Có hai loại chuỗi trong lập trình Arduino -

  • Mảng ký tự giống như chuỗi được sử dụng trong lập trình C.
  • Chuỗi Arduino, cho phép chúng ta sử dụng một đối tượng chuỗi trong bản phác thảo.

Trong chương này, chúng ta sẽ tìm hiểu Chuỗi, đối tượng và việc sử dụng chuỗi trong các bản phác thảo Arduino. Đến cuối chương, bạn sẽ biết loại chuỗi nào sẽ sử dụng trong bản phác thảo.

Mảng ký tự chuỗi

Loại chuỗi đầu tiên mà chúng ta sẽ học là chuỗi là một chuỗi các ký tự thuộc loại char. Trong chương trước, chúng ta đã học mảng là gì; một chuỗi liên tiếp của cùng một loại biến được lưu trữ trong bộ nhớ. Chuỗi là một mảng các biến char.

Chuỗi là một mảng đặc biệt có thêm một phần tử ở cuối chuỗi, phần tử này luôn có giá trị 0 (không). Điều này được gọi là "chuỗi kết thúc null".

Ví dụ về mảng ký tự chuỗi

Ví dụ này sẽ chỉ ra cách tạo một chuỗi và in nó ra cửa sổ giám sát nối tiếp.

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() { 

}

Ví dụ sau đây cho thấy chuỗi được tạo thành từ gì; một mảng ký tự với các ký tự có thể in được và 0 là phần tử cuối cùng của mảng để chỉ ra rằng đây là nơi chuỗi kết thúc. Chuỗi có thể được in ra cửa sổ Arduino IDE Serial Monitor bằng cách sử dụngSerial.println() và chuyển tên của chuỗi.

Ví dụ tương tự này có thể được viết theo cách thuận tiện hơn như hình dưới đây:

Example

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

void loop() {

}

Trong bản phác thảo này, trình biên dịch sẽ tính toán kích thước của mảng chuỗi và cũng tự động kết thúc chuỗi bằng số không null. Một mảng dài sáu phần tử và bao gồm năm ký tự theo sau là số 0 được tạo theo cách giống hệt như trong bản phác thảo trước.

Thao tác với Mảng chuỗi

Chúng ta có thể thay đổi một mảng chuỗi trong một bản phác thảo như thể hiện trong bản phác thảo sau.

Thí dụ

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() {

}

Kết quả

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

Bản phác thảo hoạt động theo cách sau.

Tạo và in chuỗi

Trong bản phác thảo ở trên, một chuỗi mới được tạo và sau đó được in ra để hiển thị trong cửa sổ Serial Monitor.

Rút ngắn chuỗi

Chuỗi được rút ngắn bằng cách thay thế ký tự thứ 14 trong chuỗi bằng ký tự null kết thúc bằng 0 (2). Đây là phần tử số 13 trong mảng chuỗi đếm từ 0.

Khi chuỗi được in, tất cả các ký tự được in đến giá trị rỗng mới kết thúc bằng 0. Các ký tự khác không biến mất; chúng vẫn tồn tại trong bộ nhớ và mảng chuỗi vẫn có kích thước như cũ. Sự khác biệt duy nhất là bất kỳ hàm nào hoạt động với chuỗi sẽ chỉ thấy chuỗi có tới ký tự kết thúc null đầu tiên.

Thay đổi một từ trong chuỗi

Cuối cùng, bản phác thảo thay thế từ "bánh" bằng "trà" (3). Đầu tiên, nó phải thay thế dấu chấm dứt null tại như [13] bằng một khoảng trắng để chuỗi được khôi phục về định dạng được tạo ban đầu.

Các ký tự mới ghi đè "cak" của từ "cake" bằng từ "tea". Điều này được thực hiện bằng cách ghi đè các ký tự riêng lẻ. Chữ 'e' của "cake" được thay thế bằng một ký tự kết thúc bằng null mới. Kết quả là chuỗi thực sự được kết thúc bằng hai ký tự null, ký tự gốc ở cuối chuỗi và ký tự mới thay thế 'e' trong "cake". Điều này không có gì khác biệt khi chuỗi mới được in bởi vì hàm in chuỗi ngừng in các ký tự chuỗi khi nó gặp dấu chấm hết null đầu tiên.

Các chức năng để thao tác với mảng chuỗi

Bản phác thảo trước đã thao tác chuỗi theo cách thủ công bằng cách truy cập các ký tự riêng lẻ trong chuỗi. Để thao tác với mảng chuỗi dễ dàng hơn, bạn có thể viết các hàm của riêng mình để làm như vậy hoặc sử dụng một số hàm chuỗi từC thư viện ngôn ngữ.

Không. Chức năng & Mô tả
1

String()

Lớp String, một phần cốt lõi của phiên bản 0019, cho phép bạn sử dụng và thao tác các chuỗi văn bản theo những cách phức tạp hơn so với mảng ký tự. Bạn có thể nối các Chuỗi, nối vào chúng, tìm kiếm và thay thế các chuỗi con, v.v. Nó chiếm nhiều bộ nhớ hơn một mảng ký tự đơn giản, nhưng nó cũng hữu ích hơn.

Để tham khảo, các mảng ký tự được gọi là chuỗi có chữ 's' nhỏ và các trường hợp của lớp String được gọi là Chuỗi có chữ S. Lưu ý rằng các chuỗi không đổi, được chỉ định trong "dấu ngoặc kép" được coi là mảng char, không phải phiên bản của lớp String

2

charAt()

Truy cập một ký tự cụ thể của Chuỗi.

3

compareTo()

So sánh hai Chuỗi, kiểm tra xem một chuỗi đến trước hay sau chuỗi kia, hoặc liệu chúng có bằng nhau hay không. Các chuỗi được so sánh từng ký tự, sử dụng các giá trị ASCII của các ký tự. Điều đó có nghĩa là, ví dụ, 'a' đứng trước 'b' nhưng sau 'A'. Các con số đứng trước các chữ cái.

4

concat()

Thêm tham số vào một chuỗi.

5

c_str()

Chuyển đổi nội dung của một chuỗi thành một chuỗi kiểu C, kết thúc bằng null. Lưu ý rằng điều này cho phép truy cập trực tiếp vào bộ đệm Chuỗi bên trong và cần được sử dụng cẩn thận. Đặc biệt, bạn không bao giờ được sửa đổi chuỗi thông qua con trỏ được trả về. Khi bạn sửa đổi đối tượng String hoặc khi nó bị phá hủy, bất kỳ con trỏ nào được trả về trước đó bởi c_str () sẽ trở nên không hợp lệ và không được sử dụng nữa.

6

endsWith()

Kiểm tra xem một Chuỗi có kết thúc bằng các ký tự của Chuỗi khác hay không.

7

equals()

So sánh hai chuỗi cho bằng nhau. So sánh có phân biệt chữ hoa chữ thường, nghĩa là Chuỗi "xin chào" không bằng Chuỗi "HELLO".

số 8

equalsIgnoreCase()

So sánh hai chuỗi cho bằng nhau. So sánh không phân biệt chữ hoa chữ thường, có nghĩa là Chuỗi ("xin chào") bằng với Chuỗi ("HELLO").

9

getBytes()

Sao chép các ký tự của chuỗi vào bộ đệm được cung cấp.

10

indexOf()

Định vị một ký tự hoặc Chuỗi trong một Chuỗi khác. Theo mặc định, nó tìm kiếm từ đầu Chuỗi, nhưng cũng có thể bắt đầu từ một chỉ mục nhất định, cho phép xác định vị trí tất cả các phiên bản của ký tự hoặc Chuỗi.

11

lastIndexOf()

Định vị một ký tự hoặc Chuỗi trong một Chuỗi khác. Theo mặc định, nó tìm kiếm từ cuối Chuỗi, nhưng cũng có thể hoạt động ngược lại từ một chỉ mục nhất định, cho phép xác định vị trí tất cả các phiên bản của ký tự hoặc Chuỗi.

12

length()

Trả về độ dài của Chuỗi, tính bằng ký tự. (Lưu ý rằng điều này không bao gồm một ký tự null ở cuối.)

13

remove()

Sửa đổi tại chỗ, một chuỗi loại bỏ các ký tự từ chỉ mục được cung cấp đến cuối chuỗi hoặc từ chỉ mục được cung cấp thành chỉ mục cộng với số lượng.

14

replace()

Hàm String Replace () cho phép bạn thay thế tất cả các trường hợp của một ký tự nhất định bằng một ký tự khác. Bạn cũng có thể sử dụng thay thế để thay thế các chuỗi con của một chuỗi bằng một chuỗi con khác.

15

reserve()

Hàm String Reserve () cho phép bạn cấp phát một vùng đệm trong bộ nhớ để thao tác với các chuỗi.

16

setCharAt()

Đặt một ký tự của Chuỗi. Không ảnh hưởng đến các chỉ số bên ngoài độ dài hiện có của Chuỗi.

17

startsWith()

Kiểm tra xem một Chuỗi có bắt đầu bằng các ký tự của Chuỗi khác hay không.

18

toCharArray()

Sao chép các ký tự của chuỗi vào bộ đệm được cung cấp.

19

substring()

Nhận một chuỗi con của một Chuỗi. Chỉ mục bắt đầu là bao gồm (ký tự tương ứng được bao gồm trong chuỗi con), nhưng chỉ mục kết thúc tùy chọn là loại trừ (ký tự tương ứng không được bao gồm trong chuỗi con). Nếu chỉ mục kết thúc bị bỏ qua, chuỗi con tiếp tục đến cuối Chuỗi.

20

toInt()

Chuyển đổi một chuỗi hợp lệ thành một số nguyên. Chuỗi đầu vào phải bắt đầu bằng một số nguyên. Nếu chuỗi chứa các số không phải số nguyên, hàm sẽ ngừng thực hiện chuyển đổi.

21

toFloat()

Chuyển đổi một chuỗi hợp lệ thành một số thực. Chuỗi đầu vào phải bắt đầu bằng một chữ số. Nếu chuỗi chứa các ký tự không phải chữ số, hàm sẽ ngừng thực hiện chuyển đổi. Ví dụ: các chuỗi "123.45", "123" và "123fish" lần lượt được chuyển đổi thành 123,45, 123,00 và 123,00. Lưu ý rằng "123.456" là gần đúng với 123,46. Cũng lưu ý rằng float chỉ có độ chính xác 6-7 chữ số thập phân và các chuỗi dài hơn có thể bị cắt bớt.

22

toLowerCase()

Nhận phiên bản viết thường của Chuỗi. Kể từ phiên bản 1.0, toLowerCase () sửa đổi chuỗi tại chỗ thay vì trả về chuỗi mới.

23

toUpperCase()

Nhận phiên bản viết hoa của một Chuỗi. Kể từ phiên bản 1.0, toUpperCase () sửa đổi chuỗi tại chỗ thay vì trả lại chuỗi mới.

24

trim()

Nhận phiên bản của Chuỗi với bất kỳ khoảng trắng đầu và cuối bị xóa. Kể từ 1.0, trim () sửa đổi chuỗi tại chỗ thay vì trả về chuỗi mới.

Bản phác thảo tiếp theo sử dụng một số hàm chuỗi C.

Thí dụ

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() {

}

Kết quả

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

Bản phác thảo hoạt động theo cách sau.

In chuỗi

Chuỗi mới tạo được in ra cửa sổ Serial Monitor như được thực hiện trong các bản phác thảo trước đó.

Nhận độ dài của chuỗi

Hàm strlen () được dùng để lấy độ dài của chuỗi. Độ dài của chuỗi chỉ dành cho các ký tự có thể in được và không bao gồm dấu chấm dứt rỗng.

Chuỗi chứa 17 ký tự, vì vậy chúng ta thấy 17 được in trong cửa sổ Serial Monitor.

Nhận chiều dài của mảng

Toán tử sizeof () được sử dụng để lấy độ dài của mảng có chứa chuỗi. Độ dài bao gồm dấu chấm hết null, do đó độ dài lớn hơn độ dài của chuỗi một lần.

sizeof () trông giống như một hàm, nhưng về mặt kỹ thuật là một toán tử. Nó không phải là một phần của thư viện chuỗi C, nhưng được sử dụng trong bản phác thảo để hiển thị sự khác biệt giữa kích thước của mảng và kích thước của chuỗi (hoặc độ dài chuỗi).

Sao chép một chuỗi

Hàm strcpy () được sử dụng để sao chép chuỗi str [] sang mảng out_num []. Hàm strcpy () sao chép chuỗi thứ hai được chuyển cho nó vào chuỗi đầu tiên. Một bản sao của chuỗi hiện tồn tại trong mảng out_num [], nhưng chỉ chiếm 18 phần tử của mảng, vì vậy chúng ta vẫn còn 22 phần tử char trống trong mảng. Các phần tử miễn phí này được tìm thấy sau chuỗi trong bộ nhớ.

Chuỗi đã được sao chép vào mảng để chúng ta có thêm một số khoảng trống trong mảng để sử dụng trong phần tiếp theo của bản phác thảo, tức là thêm một chuỗi vào cuối chuỗi.

Nối một chuỗi vào một chuỗi (Concatenate)

Phác thảo nối một chuỗi này với một chuỗi khác, được gọi là nối. Điều này được thực hiện bằng cách sử dụng hàm strcat (). Hàm strcat () đặt chuỗi thứ hai được chuyển cho nó vào cuối chuỗi đầu tiên được chuyển cho nó.

Sau khi nối, độ dài của chuỗi được in ra để hiển thị độ dài chuỗi mới. Độ dài của mảng sau đó được in ra để cho thấy rằng chúng ta có một chuỗi dài 25 ký tự trong một mảng dài 40 phần tử.

Hãy nhớ rằng chuỗi dài 25 ký tự thực sự chiếm 26 ký tự của mảng vì giá trị null kết thúc bằng 0.

Array Bounds

Khi làm việc với chuỗi và mảng, điều rất quan trọng là phải làm việc trong giới hạn của chuỗi hoặc mảng. Trong bản phác thảo ví dụ, một mảng đã được tạo, dài 40 ký tự, để cấp phát bộ nhớ có thể được sử dụng để thao tác các chuỗi.

Nếu mảng được tạo quá nhỏ và chúng tôi cố gắng sao chép một chuỗi lớn hơn mảng vào nó, chuỗi đó sẽ được sao chép qua phần cuối của mảng. Bộ nhớ ngoài phần cuối của mảng có thể chứa dữ liệu quan trọng khác được sử dụng trong bản phác thảo, sau đó sẽ được ghi đè bởi chuỗi của chúng ta. Nếu bộ nhớ vượt quá cuối chuỗi bị chạy quá mức, nó có thể làm hỏng bản phác thảo hoặc gây ra hành vi không mong muốn.