[英]Extracting int from String on Arduino
我有一個隨機字符緩沖區,它從XBee模塊流到Arduino中。 我想提取它看到的第一個整數(如果有區別,將為<= 3位數整數),然后繼續使用該數字並停止查看其余的傳入字符。
作為參考,我正在嘗試將它用作與node.js服務器進行2次握手的一部分,當其他Arduino也嘗試握手或已經連接並發送數據時,不會弄亂它。
我認為我有一種可能可以提取一個int的方法,但是它看起來確實很丑陋,因此我認為必須采用一種更短/更干凈的方法來實現此目的。 這是我很長的代碼,可能要做的很簡單:
String intString = "";
int intStart = 0;
for (int i = 0; i < msg.length(); i++) {
while (intStart != 2) {
if (intStart == 0) {
if ((msg[i] == '0') || (msg[i] == '1') || (msg[i] == '2') ||
(msg[i] == '3') || (msg[i] == '4') || (msg[i] == '5') ||
(msg[i] == '6') || (msg[i] == '7') || (msg[i] == '8') ||
(msg[i] == '9')) {
intString += msg[i];
intStart = 1;
}
}
// previous int, next is still int
if (intStart == 1) {
if ((msg[i] == '0') || (msg[i] == '1') || (msg[i] == '2') ||
(msg[i] == '3') || (msg[i] == '4') || (msg[i] == '5') ||
(msg[i] == '6') || (msg[i] == '7') || (msg[i] == '8') ||
(msg[i] == '9')) {
intString += msg[i];
intStart = 1;
}
}
// previous int, next is not int
else if ((msg[i] != '0') && (msg[i] != '1') && (msg[i] != '2') &&
(msg[i] != '3') && (msg[i] != '4') && (msg[i] == '5') &&
(msg[i] != '6') && (msg[i] != '7') && (msg[i] == '8') &&
(msg[i] != '9')) {
intStart = 2;
}
}
}
int number = intString.toInt();
Serial.println(number);
任何建議/建議,不勝感激。
不要使用標准C函數isdigit()
與0到9之間的每個數字進行比較。
String intString = "";
int intStart = 0;
for (int i = 0; i < msg.length(); i++) {
while (intStart != 2) {
if (intStart == 0) {
if (isdigit(msg[i])){
intString += msg[i];
intStart = 1;
}
}
// previous int, next is still int
if (intStart == 1) {
if (isdigit(msg[i])) {
intString += msg[i];
intStart = 1;
}
}
// previous int, next is not int
else if ( isdigit(msg[i]) ) {
intStart = 2;
}
}
}
“橡皮鴨調試” :
假設味精的第一個字符是一個數字:
intStart
設置為0
intStart
是2
如果intStart
為0(即我們尚未對其進行調整),並且味精的第一個字符為digit(我們假定為),則將第一個字符附加到intString
,並使intStart = 1
如果intStart == 1
( intStart == 1
,我們在上一步中將其設置),而味精的第一個字符是digit(它仍然是第一個, i
沒有改變),然后將第一個字符附加到intString
(很好,現在我有兩次)並設置intStart=1
(嘿, intStart
沒變)。 否則,我們可以忽略其他情況, then
我們處於良好狀態 intStart==1
, i
仍然為0,味精的第一個字符仍然為數字。 我應該繼續還是您能夠做到?
本質上,由於msg的第一個字符為數字,因此直到intString
不斷重復使用相同的intString
char來增長intString
之前,您永遠不會退出while (intStart != 2)
。
那是你要的嗎?
在問SO之前向您的橡皮鴨解釋這個問題是如此難嗎?
(是的,我知道,Arduino沒有調試器,但是您仍然可以使用Serial.print)
[評論更新]
抱歉,如果我不清楚,但不一定以整數開頭,則該整數可能位於char緩沖區的中間。
char緩沖區中任意長度的第一個數字序列(實際上不必限制為最大3位數,只要它使它更容易)
因此,在開始收集之前,我們只需要將自己放置在字符串緩沖區的第一位
int startScan=0;
// no body for the cycle, everything works just from
// the exit condition and increment
for(
;
startScan < msg.length() && ! isdigit(msg[i]); // as long as it's not a digit
startScan++
);
// from this position, start collecting for as long as we have digits
int intValue=0;
String intString;
for(; startScan < msg.length() && isdigit(msg[startScan]); startScan++) {
intString += msg[startScan]; // take it inside the string
// careful with this one, it may overflow if too many digits
intValue = intValue*10 + (msg[startScan]-'0');
}
// if we reached here with an empty intString, we didn't find any digits
如果您不需要intString
, intString
需要intValue
,不要使用intString
最多將bool hasDigits
初始化為false
並設置為true
代替intString += msg[startScan];
(作為“未遇到數字”情況的信號)。
如果不需要intValue
,只需從使用它的代碼中清除即可。
因此,如果我的陳述不足,那么您將遇到以下問題:
我有一個
String
消息,該消息最多以 3個十進制數字開頭,並可能以我不需要的其他信息結尾。 我希望將“至多3個數字”前綴轉換為整數,以便我進一步使用
如果這是您的問題,請嘗試以下操作:
int intValue=0;
String intString;
int maxLookInto=(msg.length() > 3 ? 3 : msg.length()); // at most 3 digits
for(int i=0; i<maxLookInto && isdigit(msg[i]); i++) {
// if we got here, we know msg[i] is still a digit, otherwise
// we get out of cycle ealier
intString += msg[i]; // take it inside the string
intValue = intValue*10 + (msg[i]-'0'); // transforming in base 10 in an int
}
// Do what you like with either intString (textual representation of the
// at-most-3-digits or with the same value converted already to a number
// in intValue
如果Arduino沒有提供isdigit
功能,則可以實現自己的
int isdigit(char c) {
// we are using ASCII encoding for characters, aren't we?
return (c>='0' && c <='9');
}
順便說一句,有一個特定於Arduino的堆棧交換。 arduino.stackexchange.com
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.