我正在开发一个关于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
答案 0 :(得分:4)
我不确定在Arduino上使用了什么工具集。有时库会支持非标准的“千元分组”标志 - 单引号字符是典型的扩展名:
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;
}
答案 1 :(得分:1)
也许不是最佳算法,但这是一个实现示例(标准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;
}
答案 2 :(得分:0)
您可以尝试以下方法:
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();
}
代码是时髦的镜头,但这个想法应该有用。
答案 3 :(得分:0)
也许可以帮助您。 我用这个草图在arduino LCD上制作了数千个分隔符。
int n;
n = 0;
char number[9];
sscanf(buffer, " %8[0-9] %n", number, &n);
if (n == 0) return fail; // no digits
if (buf[n]) return fail; // junk after the digits
if (strlen(buf) != 7) return fail; // not 7 digits
Success();
}
此草图称为子例程(void TulisanDesimaBeli)
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//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);
}
}
}
对不起,我的英语不好,您可以在https://youtu.be/baYdiqqfr3c分钟1.30观看
或访问http://www.radixrobotic.id/project/arduino-tiket-printer-epson-tm-u220/
访问我的网站升级。