thiet bi arduino

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ữ đầ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 các ký tự, giống như các 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ẽ tìm hiểu loại chuỗi nào để 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ự kiểu 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ớ. Một 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, luôn có giá trị 0 (không). Đâ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.

Thí dụ

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 một chuỗi được tạo thành từ những 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ụng Serial.println () và chuyển tên của chuỗi.

Arduino - 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:

Thí dụ

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ư được hiển thị 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ó cùng kích thướ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ó đến 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 [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 cuối null đầu tiên.

Các hàm để 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ừ thư viện ngôn ngữ C.

Dưới đây là danh sách các Hàm để Thao tác Mảng Chuỗi

S.No.Functions & Description
1String() The String class, part of the core as of version 0019, allows you to use and manipulate strings of text in more complex ways than character arrays do. You can concatenate Strings, append to them, search for and replace substrings, and more. It takes more memory than a simple character array, but it is also more useful. For reference, character arrays are referred to as strings with a small ‘s’, and instances of the String class are referred to as Strings with a capital S. Note that constant strings, specified in “double quotes” are treated as char arrays, not instances of the String class
2charAt() Access a particular character of the String.
3compareTo() Compares two Strings, testing whether one comes before or after the other, or whether they are equal. The strings are compared character by character, using the ASCII values of the characters. That means, for example, ‘a’ comes before ‘b’ but after ‘A’. Numbers come before letters.
4concat() Appends the parameter to a String.
5c_str() Converts the contents of a string as a C-style, null-terminated string. Note that this gives direct access to the internal String buffer and should be used with care. In particular, you should never modify the string through the pointer returned. When you modify the String object, or when it is destroyed, any pointer previously returned by c_str() becomes invalid and should not be used any longer.
6endsWith() Tests whether or not a String ends with the characters of another String.
7equals() Compares two strings for equality. The comparison is case-sensitive, meaning the String “hello” is not equal to the String “HELLO”.
8equalsIgnoreCase() Compares two strings for equality. The comparison is not case-sensitive, meaning the String(“hello”) is equal to the String(“HELLO”).
9getBytes() Copies the string’s characters to the supplied buffer.
10indexOf() Locates a character or String within another String. By default, it searches from the beginning of the String, but can also start from a given index, allowing to locate all instances of the character or String.
11lastIndexOf() Locates a character or String within another String. By default, it searches from the end of the String, but can also work backwards from a given index, allowing to locate all instances of the character or String.
12length() Returns the length of the String, in characters. (Note that this does not include a trailing null character.)
13remove() Modify in place, a string removing chars from the provided index to the end of the string or from the provided index to index plus count.
14replace() The String replace() function allows you to replace all instances of a given character with another character. You can also use replace to replace substrings of a string with a different substring.
15reserve() The String reserve() function allows you to allocate a buffer in memory for manipulating strings.
16setCharAt() Sets a character of the String. Has no effect on indices outside the existing length of the String.
17startsWith() Tests whether or not a String starts with the characters of another String.
18toCharArray() Copies the string’s characters to the supplied buffer.
19substring() Get a substring of a String. The starting index is inclusive (the corresponding character is included in the substring), but the optional ending index is exclusive (the corresponding character is not included in the substring). If the ending index is omitted, the substring continues to the end of the String.
20toInt() Converts a valid String to an integer. The input string should start with an integer number. If the string contains non-integer numbers, the function will stop performing the conversion.
21toFloat() Converts a valid String to a float. The input string should start with a digit. If the string contains non-digit characters, the function will stop performing the conversion. For example, the strings “123.45”, “123”, and “123fish” are converted to 123.45, 123.00, and 123.00 respectively. Note that “123.456” is approximated with 123.46. Note too that floats have only 6-7 decimal digits of precision and that longer strings might be truncated.
22toLowerCase() Get a lower-case version of a String. As of 1.0, toLowerCase() modifies the string in place rather than returning a new.
23toUpperCase() Get an upper-case version of a String. As of 1.0, toUpperCase() modifies the string in place rather than returning a new one.
24trim() Get a version of the String with any leading and trailing whitespace removed. As of 1.0, trim() modifies the string in place rather than returning a new one.

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 () 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, vì vậy độ 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 [] vào 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)

Arduino - Chuỗi

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.

Arduino – Đối tượng chuỗi

Loại chuỗi thứ hai được sử dụng trong lập trình Arduino là Đối tượng chuỗi.

Đối tượng là gì?

Đối tượng là một cấu trúc chứa cả dữ liệu và hàm. Một đối tượng String có thể được tạo giống như một biến và được gán một giá trị hoặc chuỗi. Đối tượng String chứa các hàm (được gọi là “phương thức” trong lập trình hướng đối tượng (OOP)) hoạt động trên dữ liệu chuỗi có trong đối tượng String.

Bản phác thảo và giải thích sau đây sẽ làm rõ đối tượng là gì và đối tượng String được sử dụng như thế nào.

Thí dụ

void setup() { 
   String my_str = "This is my string.";
   Serial.begin(9600);

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

   // (2) change the string to upper-case
   my_str.toUpperCase();
   Serial.println(my_str);

   // (3) overwrite the string
   my_str = "My new string.";
   Serial.println(my_str);

   // (4) replace a word in the string
   my_str.replace("string", "Arduino sketch");
   Serial.println(my_str);

   // (5) get the length of the string
   Serial.print("String length is: ");
   Serial.println(my_str.length());
}

void loop() { 

}

Kết quả

This is my string.
THIS IS MY STRING.
My new string.
My new Arduino sketch.
String length is: 22

Một đối tượng chuỗi được tạo và gán một giá trị (hoặc chuỗi) ở trên cùng của bản phác thảo.

String my_str = "This is my string." ;

Điều này tạo ra một đối tượng String với tên my_str và cung cấp cho nó một giá trị “Đây là chuỗi của tôi.”. Điều này có thể được so sánh với việc tạo một biến và gán một giá trị cho nó, chẳng hạn như một số nguyên

int my_var = 102;

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

In chuỗi

Chuỗi có thể được in ra cửa sổ Serial Monitor giống như chuỗi mảng ký tự.

Chuyển đổi chuỗi thành chữ hoa

Đối tượng chuỗi my_str đã được tạo, có một số hàm hoặc phương thức có thể hoạt động trên nó. Các phương thức này được gọi bằng cách sử dụng tên đối tượng theo sau là toán tử dấu chấm (.) Và sau đó là tên của hàm sẽ sử dụng.

my_str.toUpperCase();

Hàm toUpperCase () hoạt động trên chuỗi chứa trong đối tượng my_str có kiểu String và chuyển đổi dữ liệu chuỗi (hoặc văn bản) mà đối tượng chứa thành các ký tự viết hoa. Bạn có thể tìm thấy danh sách các hàm mà lớp String chứa trong tham chiếu Chuỗi Arduino. Về mặt kỹ thuật, String được gọi là một lớp và được sử dụng để tạo các đối tượng String.

Ghi đè một chuỗi

Toán tử gán được sử dụng để gán một chuỗi mới cho đối tượng my_str thay thế chuỗi cũ

my_str = "My new string." ;

Toán tử gán không thể được sử dụng trên chuỗi mảng ký tự, nhưng chỉ hoạt động trên các đối tượng Chuỗi.

Thay thế một từ trong chuỗi

Hàm Replace () được sử dụng để thay thế chuỗi đầu tiên được chuyển cho nó bằng chuỗi thứ hai được chuyển cho nó. Replace () là một hàm khác được tích hợp trong lớp String và do đó có sẵn để sử dụng trên đối tượng String my_str.

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

Việc lấy độ dài của chuỗi có thể dễ dàng thực hiện bằng cách sử dụng length (). Trong bản phác thảo ví dụ, kết quả trả về bởi length () được chuyển trực tiếp đến Serial.println () mà không cần sử dụng một biến trung gian.

Khi nào sử dụng một đối tượng chuỗi

Đối tượng Chuỗi dễ sử dụng hơn nhiều so với một mảng ký tự chuỗi. Đối tượng có các hàm tích hợp có thể thực hiện một số thao tác trên chuỗi.

Nhược điểm chính của việc sử dụng đối tượng String là nó sử dụng nhiều bộ nhớ và có thể nhanh chóng sử dụng hết bộ nhớ RAM của Arduinos, điều này có thể khiến Arduino bị treo, bị treo hoặc hoạt động không mong muốn. Nếu một bản phác thảo trên Arduino nhỏ và hạn chế việc sử dụng các đối tượng, thì sẽ không có vấn đề gì.

Chuỗi mảng ký tự khó sử dụng hơn và bạn có thể cần viết các hàm của riêng mình để hoạt động trên các loại chuỗi này. Ưu điểm là bạn có quyền kiểm soát kích thước của mảng chuỗi mà bạn tạo, vì vậy bạn có thể giữ các mảng nhỏ để tiết kiệm bộ nhớ.

Bạn cần đảm bảo rằng bạn không viết vượt quá giới hạn cuối của mảng với mảng chuỗi. Đối tượng String không gặp vấn đề này và sẽ chăm sóc các giới hạn của chuỗi cho bạn, miễn là có đủ bộ nhớ để nó hoạt động. Đối tượng String có thể cố gắng ghi vào bộ nhớ không tồn tại khi nó hết bộ nhớ, nhưng sẽ không bao giờ ghi vào phần cuối của chuỗi mà nó đang hoạt động.

Nơi các chuỗi được sử dụng

Trong chương này, chúng ta đã nghiên cứu về các chuỗi, cách chúng hoạt động trong bộ nhớ và các hoạt động của chúng.

Các ứng dụng thực tế của chuỗi sẽ được đề cập trong phần tiếp theo của khóa học này khi chúng ta nghiên cứu cách lấy thông tin đầu vào của người dùng từ cửa sổ Serial Monitor và lưu dữ liệu đầu vào trong một chuỗi.

Arduino – Thời gian xem thêm

Trả lời