如何在Arduino上格式化长添加数千分隔符
How to format a long adding thousands separator on Arduino
我正在开发Arduino上的一个项目,该项目解析来自远程web API的一些JSON数据,将其显示在16x2 LCD上。
我想格式化一个长解析与TextFinder添加千位分隔符(逗号分隔符将是好的)。
简而言之,我如何编写formatLong
函数?
long longToBeFormatted = 32432423;
formattedLong = formatLong(longToBeFormatted); //How to implement this?
lcd.print(formattedLong) // formattedLong is a string
我不确定在Arduino上使用什么工具集。有时库会支持一个非标准的'thousand grouping'标志——单引号字符是典型的扩展名:
printf("%'ld",long_val);
如果您的库不支持此操作,可以使用下面的代码:
#include <stddef.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <assert.h>
size_t strlcpy( char* dest, char const* src, size_t dest_size);
size_t format_long( long x, char* buf, size_t bufsize)
{
// This code assumes 32-bit long, is that the
// case on Arduino? Modifying it to be able to
// handle 64-bit longs (or to not care) should be
// pretty straightforward if that's necessary.
char scratch[sizeof("-2,147,483,648")];
char* p = scratch + sizeof(scratch); // Work from end of buffer
int neg = (x < 0);
// Handle a couple special cases
if (x == 0) {
return strlcpy( buf, "0", bufsize);
}
if (x == INT_MIN) {
// Lazy way of handling this special case
return strlcpy( buf, "-2,147,483,648", bufsize);
}
// Work with positive values from here on
if (x < 0) x = -x;
int group_counter = 3;
*(--p) = 0; // Null terminate the scratch buffer
while (x != 0) {
int digit = x % 10;
x = x / 10;
assert( p != &scratch[0]);
*(--p) = "0123456789"[digit];
if ((x != 0) && (--group_counter == 0)) {
assert( p != &scratch[0]);
*(--p) = ',';
group_counter = 3;
}
}
if (neg) {
assert( p != &scratch[0]);
*(--p) = '-';
}
return strlcpy(buf, p, bufsize);
}
/*
A non-optimal strlcpy() implementation that helps copying string
without danger of buffer overflow.
This is provided just in case you don't have an implementation
so the code above will actually compile and run.
*/
size_t strlcpy( char* dest, char const* src, size_t dest_size)
{
size_t len = strlen(src);
if (dest_size == 0) {
// nothing to copy - just return how long the buffer should be
// (note that the return value doens't include the null terminator)
return len;
}
size_t tocopy = (dest_size <= len) ? dest_size-1 : len;
memmove( dest, src, tocopy);
dest[tocopy] = 0;
return len;
}
可能不是最好的算法,但这里有一个实现示例(标准C):
char* formatLong(long toBeFormatted)
{
// Get the string representation as is
char* buffer = (char*) malloc(sizeof(long));
ltoa(toBeFormatted, buffer, 10);
// Calculate how much commas there will be
unsigned int buff_length = strlen(buffer);
unsigned int num_commas = buff_length / 3;
unsigned int digits_left = buff_length % 3;
if (digits_left == 0)
{
num_commas--;
}
// Allocate space for final string representation
unsigned int final_length = buff_length + num_commas + 1;
char* final = (char*) malloc(final_length);
memset(final, 0, final_length);
// Parse strings from last to first to count positions
int final_pos = final_length - 2;
int buff_pos = buff_length - 1;
int i = 0;
while(final_pos >= 0)
{
final[final_pos--] = buffer[buff_pos--];
i++;
if (i % 3 == 0)
{
final[final_pos--] = ',';
}
}
// Free obsolete memory and return buffer
free(buffer);
return final;
}
您可以尝试以下操作:
std::string formatLong(long l) {
int power = 0;
while (l / (pow(1000, power)) { power += 1; }
power -= 1;
std::stringstream s;
while (power) {
s << l / pow(1000, power);
s << ",";
l % (pow(1000, power));
power -= 1;
}
return s->str();
}
也许我能帮你…我用这个草图在arduino LCD上制作了千位分隔符。
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//TULISAN DENGAN SPARATOR BELI BBM
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void TulisanDesimalBeli(char customKey, String DataStr)
{
c=DataStr.length();
if (c<=7)
{
if (c<4)
{
lcd.print(customKey);
}
else if (c==4)
{
DataStr1=DataStr;
DataStr.remove(c-3);
DataStr1.remove(0,(c-3));
DataStr+="." + DataStr1;
lcd.setCursor(0,1);
lcd.print("Jml:Rp.");
lcd.print(DataStr);
}
else if ((c>4)&&(c<=6))
{
DataStr1=DataStr;
DataStr.remove(c-3);
DataStr1.remove(0,(c-3));
DataStr+="." + DataStr1;
lcd.setCursor(0,1);
lcd.print("Jml:Rp.");
lcd.print(DataStr);
}
else if (c>6)
{
DataStr1=DataStr;
DataStr.remove(c-3);
DataStr1.remove(0,(c-3));
DataStr+="." + DataStr1;
DataStr1=DataStr;
DataStr.remove((c-6));
DataStr1.remove(0,(c-6));
DataStr+="." + DataStr1;
lcd.setCursor(0,1);
lcd.print("Jml:Rp.");
lcd.print(DataStr);
}
}
}
这个草图被称为子程序(void TulisanDesimaBeli)
if ((customKey<='9')&&(customKey>='0'))
{
DataStr+=customKey;
TulisanDesimalBeli(customKey,DataStr);
a=(int)customKey&0x0F;
HarBel=HarBel*10;
HarBel=HarBel+a;
}
对不起,我的英语最差,你可以看https://youtu.be/baYdiqqfr3c分钟1.30
或访问我的网站http://www.radixrobotic.id/project/arduino-tiket-printer-epson-tm-u220/
独立。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 如何在C++中从两个单独的for循环中添加两个数组
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 如何仅为一个函数添加延迟
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 如何将更多文件夹添加到c++include路径
- 如何将元素添加到数组的线程安全函数?
- QT通过C++添加映射QML项目
- 如何将点击的信号和插槽添加到qt中的自定义按钮中
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 只能向C++添加一定数量的字符
- 当用户键入分隔符时,停止getline()输入
- 为什么不按默认构造路径划分路径只是在 Visual Studio 中添加尾随分隔符?
- 将不包含分隔符的字符串的结尾添加到向量
- 删除一个编程添加的面板分隔符在MFC Ribbon Bar
- 如何在Arduino上格式化长添加数千分隔符
- 如何实现自动添加分隔符的自定义粘性操纵器