Go Down

Topic: Right justify (Read 2455 times) previous topic - next topic

KiloOne

I would like to right justify (with space padding), a long integer in a 5 character fixed length string that can be sent out with the serial print command.

I know I likely need to use sprintf but the syntax escapes me.

What is the elegant way to do this?

pYro_65

You could use if's

Code: [Select]

if a >= 100
pad 1
else if a >= 10
pad 2
else
pad 3

itoa after padding


or use itoa and fill a buffer, count its length and shift right by appropriate spaces.

just a few thoughts

PaulS

Quote
I would like to right justify (with space padding), a long integer in a 5 character fixed length string that can be sent out with the serial print command.

If the value in the long fits in 5 spaces, does it really need to be a long?

%nd should work, where n is the number of characters to use.

KiloOne


Quote
I would like to right justify (with space padding), a long integer in a 5 character fixed length string that can be sent out with the serial print command.

If the value in the long fits in 5 spaces, does it really need to be a long?

%nd should work, where n is the number of characters to use.


Yes some values are >32768.

%nd was easy to find but I am struggling with defining my variables to do this and then getting result into serial print command.

PaulS

Quote
but I am struggling with defining my variables to do this and then getting result into serial print command.

Show some code. It should be very simple.
Code: [Select]

long val = 99847;

char buff[10];
sprintf(buff, "%5d", val);
Serial.print(buff);

KiloOne

Thanks, syntax works now.

I was trying to do this:

buff = sprintf("%5d", val);

BUT, using this code:

void loop()
{
  lcd.setCursor(0,0);
  long val = 99847;
  char buff[10];
  sprintf(buff, "%5d", val);
  lcd.print(buff);
  lcd.print(':');
}

The LCD prints -31225:


PaulS

You'll need to look up the correct type to use - d is for ints. Apparently, you need a different type for longs.

KiloOne


You'll need to look up the correct type to use - d is for ints. Apparently, you need a different type for longs.


From what I can tell there is no 'long' type specifier.  Here is the list:

A type specifier that says what type the argument data should be treated as. Possible types:
% - a literal percent character. No argument is required.
b - the argument is treated as an integer, and presented as a binary number.
c - the argument is treated as an integer, and presented as the character with that ASCII value.
d - the argument is treated as an integer, and presented as a (signed) decimal number.
e - the argument is treated as scientific notation (e.g. 1.2e+2). The precision specifier stands for the number of digits after the decimal point since PHP 5.2.1. In earlier versions, it was taken as number of significant digits (one less).
E - like %e but uses uppercase letter (e.g. 1.2E+2).
u - the argument is treated as an integer, and presented as an unsigned decimal number.
f - the argument is treated as a float, and presented as a floating-point number (locale aware).
F - the argument is treated as a float, and presented as a floating-point number (non-locale aware). Available since PHP 4.3.10 and PHP 5.0.3.
g - shorter of %e and %f.
G - shorter of %E and %f.
o - the argument is treated as an integer, and presented as an octal number.
s - the argument is treated as and presented as a string.
x - the argument is treated as an integer and presented as a hexadecimal number (with lowercase letters).
X - the argument is treated as an integer and presented as a hexadecimal number (with uppercase letters).

Am I out of luck?

Morris Dovey

There's always a better way!

KiloOne

YES!

The ld worked!

Thanks!

Morris Dovey

Or, if you don't want the overhead of sprintf(), you can do something like:

Code: [Select]
/*============================================================================*/
/* Convert unsigned long value to d-digit decimal string in local buffer      */
/*============================================================================*/
char *u2s(unsigned long x,unsigned d)
{  static char b[16];
   char *p;
   unsigned digits = 0;
   unsigned long t = x;

   do ++digits; while (t /= 10);
   // if (digits > d) d = digits; // uncomment to allow more digits than spec'd
   *(p = b + d) = '\0';
   do *--p = x % 10 + '0'; while (x /= 10);
   while (p != b) *--p = ' ';
   return b;
}
There's always a better way!

KiloOne

That is greek to me right now but it looks very nice.

How do I find out how much overhead the sprintf addition to my code costs me?

Thanks again.

Morris Dovey

Write a minimal sketch that compiles cleanly both with and without a call to sprintf() and compare the compiled file sizes. When I did that I found that sprintf() overhead to be about 1582 bytes - but I didn't try to identify how much of that was SRAM and how much was FLASH.
There's always a better way!

loopingz

I think I am trying to do the same with  a float.

Currently I do that (my value "negative" is expected to be within -100 to 40 range).

Code: [Select]
if (negative >= 99.5) {
  lcd.setCursor ( 1, 0 );
  lcd.print(negative,0);
  } 
    else { 
      if (negative>= 9.5) {   
      lcd.setCursor (2, 0);
      lcd.print(negative,0);
      }
        else {
          if (negative>=0) {
          lcd.setCursor (3, 0 );
          lcd.print(negative,0);
          }
            else {
              if( negative>-9.5){
              lcd.setCursor (2, 0);
              lcd.print(negative,0);
              }
                 else {
                   if( negative>-99.5){
                   lcd.setCursor (1, 0);
                    lcd.print(negative,0);
                   }
                     else {
                     lcd.setCursor (0, 0);
                     lcd.print(negative,0);     
                     }
                }
            }
        }
    }


I am trying to implement it this way:

Code: [Select]
lcd.setCursor (20,1);
  int negative_int = negative;
    char buff[10];
  sprintf(buff, "%4d", negative_int);
  lcd.print(buff);
  //lcd.print(':');

It takes around 1700bytes (no issue here)
I tested succesfully with values between 9999 and -999.  10000 kind of works using one extra char on the right. -1000 is doing the same.
How long should I set buff? I tried to put it at 4. Then inject a 5digit integer: program going crazy.

Any cleaner way to code that? Thanks for the help anyway.

PaulS

Quote
How long should I set buff? I tried to put it at 4. Then inject a 5digit integer: program going crazy.

If you have size 5 feet, would you buy size 4 shoes?

Why would you even consider using an array that was smaller than the number of characters in the number you want it to hold?

Don't forget that you also need to allow room for the terminating NULL that sprintf() adds.

Go Up