如何将int转换为Arduino上的string?
如何将一个int, n
转换为一个string,以便当我通过串行发送它时,它将作为string发送?
这是我迄今为止:
int ledPin=13; int testerPin=8; int n=1; char buf[10]; void setup() { pinMode(ledPin, OUTPUT); pinMode(testerPin, OUTPUT); Serial.begin(115200); } void loop() { digitalWrite(ledPin, HIGH); sprintf(buf, "Hello!%d", n); Serial.println(buf); delay(500); digitalWrite(ledPin, LOW); delay(500); n++; }
像这样使用:
String myString = String(n);
你可以在这里find更多的例子。
你可以简单地做:
Serial.println(n);
这将自动将n
转换为ASCIIstring。 请参阅Serial.println()
的文档 。
使用stdlib.h
包含的itoa()
函数
char buffer[7]; //the ASCII of the integer will be stored in this char array itoa(-31596,buffer,10); //(integer, yourBuffer, base)
这是用于将int(带符号的16位整数)转换为string的速度优化解决scheme。
这个实现避免了使用除法,因为用于Arduino的8位AVR没有硬件DIV指令,编译器把分解转换成耗时的重复减法。 因此,最快的解决scheme是使用条件分支来构buildstring。
从RAM开始准备一个固定的7字节缓冲区,以避免dynamic分配。 由于只有7个字节,固定的RAM使用成本被认为是最小的。 为了协助编译器,我们在variables声明中添加了寄存器修饰符来加速执行。
char _int2str[7]; char* int2str( register int i ) { register unsigned char L = 1; register char c; register boolean m = false; register char b; // lower-byte of i // negative if ( i < 0 ) { _int2str[ 0 ] = '-'; i = -i; } else L = 0; // ten-thousands if( i > 9999 ) { c = i < 20000 ? 1 : i < 30000 ? 2 : 3; _int2str[ L++ ] = c + 48; i -= c * 10000; m = true; } // thousands if( i > 999 ) { c = i < 5000 ? ( i < 3000 ? ( i < 2000 ? 1 : 2 ) : i < 4000 ? 3 : 4 ) : i < 8000 ? ( i < 6000 ? 5 : i < 7000 ? 6 : 7 ) : i < 9000 ? 8 : 9; _int2str[ L++ ] = c + 48; i -= c * 1000; m = true; } else if( m ) _int2str[ L++ ] = '0'; // hundreds if( i > 99 ) { c = i < 500 ? ( i < 300 ? ( i < 200 ? 1 : 2 ) : i < 400 ? 3 : 4 ) : i < 800 ? ( i < 600 ? 5 : i < 700 ? 6 : 7 ) : i < 900 ? 8 : 9; _int2str[ L++ ] = c + 48; i -= c * 100; m = true; } else if( m ) _int2str[ L++ ] = '0'; // decades (check on lower byte to optimize code) b = char( i ); if( b > 9 ) { c = b < 50 ? ( b < 30 ? ( b < 20 ? 1 : 2 ) : b < 40 ? 3 : 4 ) : b < 80 ? ( i < 60 ? 5 : i < 70 ? 6 : 7 ) : i < 90 ? 8 : 9; _int2str[ L++ ] = c + 48; b -= c * 10; m = true; } else if( m ) _int2str[ L++ ] = '0'; // last digit _int2str[ L++ ] = b + 48; // null terminator _int2str[ L ] = 0; return _int2str; } // Usage example: int i = -12345; char* s; void setup() { s = int2str( i ); } void loop() {}
这个草图被编译为1,082字节的代码,使用与Arduino v1.0.5捆绑在一起的avr-gcc(int2str函数本身的大小是594字节)。 与使用编译为2,398字节的String对象的解决scheme相比,此实现可以将代码大小减less1.2 Kb(假定您不需要其他String的对象方法,并且您的编号对signed inttypes是严格的)。
这个函数可以通过编写正确的汇编代码进一步优化。
你只需要把它包装在一个String对象中,像这样:
String numberString = String(n);
你也可以这样做:
String stringOne = "Hello String"; // using a constant String String stringOne = String('a'); // converting a constant char into a String String stringTwo = String("This is a string"); // converting a constant string into a String object String stringOne = String(stringTwo + " with more"); // concatenating two strings String stringOne = String(13); // using a constant integer String stringOne = String(analogRead(0), DEC); // using an int and a base String stringOne = String(45, HEX); // using an int and a base (hexadecimal) String stringOne = String(255, BIN); // using an int and a base (binary) String stringOne = String(millis(), DEC); // using a long and a base
解决scheme太大了。 试试这个简单的。 请提供7个字符以上的缓冲区,不作任何检查。
char *i2str(int i, char *buf){ byte l=0; if(i<0) buf[l++]='-'; boolean leadingZ=true; for(int div=10000, mod=0; div>0; div/=10){ mod=i%div; i/=div; if(!leadingZ || i!=0){ leadingZ=false; buf[l++]=i+'0'; } i=mod; } buf[l]=0; return buf; }
如果丢弃索引'l'并直接递增缓冲区,可以很容易地修改缓冲区的末尾。
在第一个例子中,使用了一个经典的Cstring:它只是一个以零(NUL字符)结尾的字符数组。 其他的例子使用了String类,这是一个C ++类,除了玩具例子和小样本之外,我将远离它。 它以不太容易预测的方式泄漏内存,并导致板卡的神秘locking。