در قسمت نهم از آموزش آردوینو به بررسی استفاده از تابع رشتهای آردوینو، پرداختیم. در این قسمت قصد داریم درباره استفاده از رشتههای کاراکتری زبان C و تقسیم متن جدا شده با کاما (Comma-Separated) صحبت کنیم.
در ابتدای این مطلب چگونگی استفاده از رشتههای کاراکتری را بررسی خواهیم کرد. همچنین، یاد خواهید گرفت که چگونه یک رشته (string) ایجاد، طول آن را اندازهگیری و رشتهها را مقایسه، کپی یا اضافه کنید.
استفاده از رشتههای کاراکتری در توابع
آرایههای کاراکتری را رشتههای کاراکتری نیز مینامند. در قسمت هشتم این آموزش، آرایههای آردوینو را بهصورت کامل بررسی کردیم. در این قسمت چگونگی استفاده از رشتههای کاراکتری در توابع توضیح داده شدند. اگر تابهحال برنامهنویسی زبان C یا C++ کار کرده باشید، احتمالاً عادت دارید که #include <string.h> را به کد خود اضافه کنید تا با این کار، به این توابع دسترسی داشته باشید. نرمافزار Arduino IDE این کار را بهصورت اتوماتیک برای شما انجام میدهد، بنابراین دیگر شما نیازی به اضافهکردن #include <string.h> ندارید.
رشتهها را باید به صورت زیر بنویسید:
char stringA[8]; // declare a string of up to 7 chars plus terminating null
char stringB[8] = “Arduino”; // as above and initialize the string to “Arduino”
char stringC[16] = “Arduino”; // as above, but string has room to grow
char stringD[ ] = “Arduino”; // the compiler inits string and calculates size
بهطورکلی، تابع strlen (مخفف string length) در زبان C++ برای محاسبه تعداد کاراکترهای قبل از کاراکتر null، استفاده میشود:
1 | int length = strlen(string); // return the number of characters in the string |
برای مثال برای محاسبه طول رشته stringA با استفاده از تابع strlen() مقدار ۷ را برمیگرداند. توجه داشته باشید که کاراکتر null در پایان رشته محاسبه نمیگردد.
از تابع strcpy (مخفف string copy) برای کپیکردن یک رشته در رشته دیگر استفاده میشود:
1 | strcpy(destination, source); // copy string source to destination |
از تابع strncpy برای محدودکردن تعداد کاراکترهایی که باید کپی شوند، استفاده کنید. (این کار برای جلوگیری از نوشتن کاراکترهای بیشتر از ظرفیت رشته مقصد (رشتههدف)، مفید است).
1 2 | // copy up to 6 characters from source to destination strncpy(destination, source, 6); |
همچنین، شما میتوانید از تابع strcat (مخفف string concatenate) برای اتصال یک رشته به انتهای رشته دیگر استفاده کنید:
1 2 | // append source string to the end of the destination string strcat(destination, source); |
نکته✅
شما میتوانید برای مقایسه دو رشته از تابع strcmp (مخفف string compare) استفاده کنید:
1 2 3 4 | if(strcmp(str, "Arduino") == 0) { // do something if the variable str is equal to "Arduino" } |
نتیجه⚡
در محیط آردوینو، متن با استفاده از آرایهای از کاراکترها به نام رشتهها (Strings) نمایش داده میشود. یک رشته از تعدادی کاراکتر تشکیل شده است که پس از آن یک کاراکتر null (مقدار 0) قرار دارد. کاراکتر null نمایش داده نمیشود، فقط نشاندهنده پایان رشته است.
توابعی که در این قسمت توضیح داده شدهاند، بخشی از کتابخانه C’s string.h هستند. شما میتوانید منابع آموزش آنلاین C/C++ را در صفحات cplusplus.com و C++ Referencepage مشاهده کنید.
تقسیم متن جدا شده با کاما (Comma-Separated)
فرض کنید شما یک رشته (string) دارید که شامل دو یا چند قسمت داده است؛ در این صورت، اگر این رشته را با کاما (یا هر جداکننده دیگری) به چند قسمت، تقسیم کنید، میتوانید از هر کدام از این رشته ها به صورت رشته های جداگانه استفاده کنید.
اسکچ زیر متن موجود بین هر کاما را چاپ میکند:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | * SplitSplit sketch * split a comma - separated string * / String text = "Peter,Paul,Mary"; // an example string String message = text; // holds text not yet split int commaPosition; // the position of the next comma in the string void setup() { Serial.begin(9600); while (!Serial); // Wait for serial port (Leonardo, 32-bit boards) Serial.println(message); // show the source string do { commaPosition = message.indexOf(','); if (commaPosition != -1) { Serial.println(message.substring(0, commaPosition)); message = message.substring(commaPosition + 1, message.length()); } else { // here after the last comma is found if (message.length() > 0) Serial.println(message); // if there is text after the last comma, // print it } } while (commaPosition >= 0); } void loop() {} //The Serial Monitor will display the following: //Peter,Paul,Mary //Peter //Paul //Mary |
همچنین، سریال مانیتور موارد زیر را نمایش می دهد:
Peter,Paul,Mary
Peter
Paul
Mary
این اسکچ از توابع String برای پیدا کردن متن از بین کاما، استفاده میکند. کد آن به صورت زیر است:
1 | commaPosition = message.indexOf(','); |
متغیر commaPosition موقعیت اولین کاما در رشتهی message ذخیره می کند (اگر کاما پیدا نشود، مقدار 1- برمیگرداند). اما اگر کاما وجود داشته باشد، تابع substring با گرفتن اندیس ابتدایی و انتهایی مقدار بین این دو اندیس را به صورت یک رشته برمیگرداند و کامای انتهایی آن در کد زیر از پیام حذف میشود:
1 | message = message.substring(commaPosition+1, message.length()); |
تابع substring رشتهای را برمیگرداند که از commaPosition+1 (موقعیت بعد از اولین کاما) شروع میشود و طول به اندازه message.length() است. این پیغام فقط حاوی متنی است که پس از کاما اول قرار دارد. این کار تا زمانی تکرار میشود که کاما دیگری پیدا نشود (commaPosition برابر با 1- خواهد بود)
اگر شما یک برنامهنویس باتجربه هستید، میتوانید از توابع سطح پایین (low-level) که بخشی از کتابخانه استاندارد C هستند، نیز استفاده کنید. با استفاده از رشتههای آردوینو، اسکچ زیر عملکردی مشابه با قبلی دارد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | * strtok sketch * split a comma - separated string * / const int MAX_STRING_LEN = 20; // set this to the largest string // you will process char stringList[] = "Peter,Paul,Mary"; // an example string char stringBuffer[MAX_STRING_LEN + 1]; // static buffer for computation/output void setup() { Serial.begin(9600); while (!Serial); // Wait for serial port (Leonardo, 32-bit boards) char * str; char * p; strncpy(stringBuffer, stringList, MAX_STRING_LEN); // copy source string Serial.println(stringBuffer); // show the source string for (str = strtok_r(stringBuffer, ",", & p); // split using comma str; // while str is not null str = strtok_r(NULL, ",", & p) // get subsequent tokens ) { Serial.println(str); } } void loop() { } |
نکته✅
در اینجا، تابع اصلی، تابعی به نام strtok_r (نام نسخه strtok که با کامپایلر آردوینو ارائه میشود) میباشد.
اولین باری که تابع strtok_r فراخوانده میشود، شما باید رشتهای را که میخواهید توکن کنید(به مقادیر جداگانه تقسیم کنید)، ارسال نمایید. اما هر بار که strtok_r، یک توکن جدید پیدا میکند، کاراکترهای این رشته را بازنویسی میکند؛ بنابراین بهتر است یک کپی از رشته را برای این تابع ارسال کنید همانطور که در این مثال نشاندادهشده است.
پس از فراخوانی اول، از یک کاراکتر NULL به عنوان ارگومان ورودی استفاده میکند تا به تابع بگوید که باید به توکن بعدی برود. در این مثال، هر توکن در پورت سریال چاپ میشود. *p پوینتری است که strtok_r از آن برای پیگیری رشتهای که روی آن کار میکند، استفاده مینماید.
اگر توکنهای شما فقط از اعداد تشکیل شده است، در قسمتهای بعدی این آموزش همراه ما باشید تا استخراج مقادیر عددی که با کاما از کاراکترهای سریال جدا شدهاند را یاد بگیرید.
برای کسب اطلاعات بیشتر در مورد توابع رشتهای زبان C مانند strtok_r به صفحه زیر مراجعه کنید:
همچنین، برای آموزش توابع C/C++ strtok_r و strcmp به سایت زیر مراجعه نمایید:
در قسمت بعدی آموزش آردوینو درباره تبدیل عدد به رشته توضیح خواهیم داد. پس در ادامه این آموزش حتماً همراه سیسوگ باشید.