Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
Torby
PostPosted: Jun 02, 2012 - 02:20 AM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

And I don't mean http://en.wikipedia.org/wiki/File:Miche ... ce2836.jpg

Want to display an integer in a 5 character space, so I put:

Code:

   char s[6];
   itoa(x, s, 10);
   while (strlen(s) < 5)
      s = strcat(" ", s);
   LCDWrites(s);


But naturally I can't find the combination needed to put a " " before the contents of s in s.

I guess I could do:
Code:

   int i = strlen(s);
   while (i>=0){
     s[i+1] = s[i];
     i -= 1;
     }
    s[0] = ' ';


inside my outer while, but you guys would laugh at such a solution (you have my permission).

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Jun 02, 2012 - 02:29 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

Torby wrote:
Code:

      s = strcat(" ", s);



Try
Code:

    strcat(s, " ");


The C string and memory functions generally take the destination as the first parameter.


EDIT: Thinking about it, it seems like you try to use this to allocate a string. You can't do that. What you were doing, was appending the contents of s to whatever memory location contained your space. While the outcome is undefined, it will clearly lead to problems. See below for the easiest way to right align stuff in a string.


Last edited by ChaunceyGardiner on Jun 02, 2012 - 02:40 AM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Jun 02, 2012 - 02:33 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

Torby wrote:
Code:

   char s[6];
   itoa(x, s, 10);
   while (strlen(s) < 5)
      s = strcat(" ", s);
   LCDWrites(s);


But naturally I can't find the combination needed to put a " " before the contents of s in s.


If you have sprintf() you can do this:
Code:

   char s[6];
   sprintf(s, "%5d", x);
   LCDWrites(s);


Last edited by ChaunceyGardiner on Jun 02, 2012 - 02:43 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
Torby
PostPosted: Jun 02, 2012 - 02:40 AM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

Don't have sprintf.

Wouldn't strcat(s, " ") put the space behind the s? I want it in front, rather like s = " " + s, if you could add strings.

I understand these aren't C++'s string class. Don't know how to use that either

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Jun 02, 2012 - 02:47 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

A bit of "post as you think of it" here - I edited my first answer before you responded.

If you don't have sprintf(), you probably have to do it manually after using itoa(). That shouldn't be too hard, though.

BTW, how do you know you don't have sprintf() ?
 
 View user's profile Send private message  
Reply with quote Back to top
Torby
PostPosted: Jun 02, 2012 - 02:57 AM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

Oh. Now I have sprintf, but now I'm at 132% of memory. Without sprintf, I'm at 51%.

Maybe I'll loop and write out spaces first, then s.

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
sternst
PostPosted: Jun 02, 2012 - 08:44 AM
Raving lunatic


Joined: Jul 23, 2001
Posts: 2438
Location: Osnabrueck, Germany

Code:
char s[6] = "     ";
char n[6];
itoa(x,n,10);
strcpy(s+5-strlen(n),n);

Code:
char n[9] = "    ";
char *s;
itoa(x,n+4,10);
s = n + strlen(n) - 5;

_________________
Stefan Ernst
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 02, 2012 - 12:12 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62299
Location: (using avr-gcc in) Finchingfield, Essex, England

I'd follow Stefan's suggestion but if you wanted to persevere with sprintf then explore using libprintf_min.a perhaps.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Jun 02, 2012 - 07:46 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2651


Torby wrote:
And I don't mean http://en.wikipedia.org/wiki/File:Miche ... ce2836.jpg

Want to display an integer in a 5 character space, so I put:

Code:

   char s[6];
   itoa(x, s, 10);
   while (strlen(s) < 5)
      s = strcat(" ", s);
   LCDWrites(s);
Code:
char s[7];  // -23456\0
itoa(x, s, 10);

unsigned char j=strlen(s), delta=sizeof(s)-1-j;
// atoa(x, s+delta, 10);
do {
    s[j+delta]=s[j];
} while(j--);

while(delta) s[--delta]=' ';
Tidier:
Code:
char s[7];  // -23456\0
itoa(x, s, 10);

unsigned sz=1+strlen(s), delta=sizeof(s)-sz;
memmove(s+delta, s, sz);
memset(s, ' ', delta);

_________________
Michael Hennebry
Iluvatar is the better part of Valar.
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Jun 03, 2012 - 02:12 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25912
Location: Wisconsin USA

Quote:

Tidier:

The approaches above are "straightforward", but "tidier" may be in the eye of the beholder.

Digest the approaches here: http://www.avrfreaks.net/index.php?name ... torder=asc Some indeed have right-justification and leading-zero-supression. (I know mine does.) Most (all?) will be smaller than full-blown printf() (if it isn't already justified for other purposes) as size seems to matter.
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Jun 03, 2012 - 10:56 PM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2651


theusch wrote:
Quote:

Tidier:

The approaches above are "straightforward", but "tidier" may be in the eye of the beholder.
The OP used strlen in a loop, so efficiency was not a criterion.
The smaller the source, the smaller the room for mess.
My tidy code also avoided explicit loops.
It is readily seen to be correct.
Since, OP didn't use it, I'd taken sprintf as unavailable.
With that limitation, the only real competitors are sternst's SRAM-wasters.
Quote:
Digest the approaches here: http://www.avrfreaks.net/index.php?name ... torder=asc Some indeed have right-justification and leading-zero-suppression. (I know mine does.) Most (all?) will be smaller than full-blown printf() (if it isn't already justified for other purposes) as size seems to matter.
At least in the current case, the job to be done is fairly clear.
BCD does not have blanks. Zero-suppression shouldn't be possible.

_________________
Michael Hennebry
Iluvatar is the better part of Valar.


Last edited by skeeve on Jun 03, 2012 - 11:46 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Jun 03, 2012 - 11:26 PM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

skeeve wrote:
With that limitation, the only real competitors are sternst's SRAM-wasters.


While I think your solution is better suited for creating flexible reusable code (i.e. a function), you can barely claim that sternst is wasting SRAM. His variable is 4 bytes bigger than yours (if he expands it to account for a possible minus sign and another character), and you generate more code than he does.

Even if you do care about those four bytes, that only lasts until the variable goes out of scope anyway - and that is something you can control if you care about it.
 
 View user's profile Send private message  
Reply with quote Back to top
skeeve
PostPosted: Jun 04, 2012 - 12:05 AM
Raving lunatic


Joined: Oct 29, 2006
Posts: 2651


ChaunceyGardiner wrote:
skeeve wrote:
With that limitation, the only real competitors are sternst's SRAM-wasters.


While I think your solution is better suited for creating flexible reusable code (i.e. a function), you can barely claim that sternst is wasting SRAM. His variable is 4 bytes bigger than yours (if he expands it to account for a possible minus sign and another character), and you generate more code than he does.
More importantly, sternst's methods are more obviously correct than mine.
I don't know why they would be any less useful in a function.
Quote:
Even if you do care about those four bytes, that only lasts until the variable goes out of scope anyway - and that is something you can control if you care about it.

_________________
Michael Hennebry
Iluvatar is the better part of Valar.
 
 View user's profile Send private message  
Reply with quote Back to top
ChaunceyGardiner
PostPosted: Jun 04, 2012 - 12:16 AM
Posting Freak


Joined: Mar 09, 2012
Posts: 1452
Location: North Carolina, USA

skeeve wrote:
More importantly, sternst's methods are more obviously correct than mine.

I don't agree with that - you both have bugs in your suggestions, but those are easy to fix and you got your ideas out there. That's the main thing.


skeeve wrote:
I don't know why they would be any less useful in a function.

I think your suggestion would be easier to implement as a function that takes the field width as an additional parameter.
 
 View user's profile Send private message  
Reply with quote Back to top
Torby
PostPosted: Jun 04, 2012 - 04:22 PM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

Working on my own before Church, I came up with

Code:

void WriteFt(long f)
{
   char s[6];
   itoa(f, s, 10);
   uint8_t i = 5 - strlen(s);
   while (i > 0) {
      LCDWritesP(Space);
      i -= 1;
   }
   LCDWrites(s);
}


But I like sternst's solution. It eats an extra variable, but that would be on the stack and vanish when the procedure exits.

Correct on efficiency. It only needs to display a few times a second, but a graceful solution is nicer to a mess.

I think I see how skeeve's solution works.

Similar puzzle is this:

x contains the answer * 10, so I want to insert a decimal point just ahead of the last character. If the decimal point lands in the first character, then insert a zero ahead of it.

Maybe:
Code:

   char s[6] ;
   itoa(x,s,10);
   uint8_t l = strlen(s);
   if (l == 1){
      s[2] = s[1];
      s[1] = s[0];
      s[0] = '0';
      l += 1;
      };
   s[l] = s[l-1] ; // Move the null
   s[l-1] = s[l-2] ; // Move the last digit
   s[l-2] = '.'; // add the .


(I typed this into the message rather than copying it from a correct program.)

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Torby
PostPosted: Jun 04, 2012 - 04:28 PM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

(Shouldn't have used small L for the variable. Can't tell it from a one.)

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
theusch
PostPosted: Jun 04, 2012 - 04:30 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25912
Location: Wisconsin USA

Quote:

At least in the current case, the job to be done is fairly clear.
BCD does not have blanks. Zero-suppression shouldn't be possible.


Huh? Didja actually read the thread? I thought it was fairly exhaustive in exploring different approaches.

danni's solution is most elegant, if the input range is limited. My utoa() is straightforward, doesn't waste any SRAM that I know of, and does both right-justification and leading-zero suppression. The latter two features are my norm when building LCD display panels.

Often I have a variant for inserting the implied decimal point. I find the above to be "better" in the long run versus a post-processing pass on the string.

All that said, if itoa() and strlen() and strcpy()/memcpy() are used elsewhere in the app, the the code footprint for this purpose is essentially 0 and itoa() is usually fairly efficient. So for a uint16_t with max value of 50000 are you going to do ltoa()?
 
 View user's profile Send private message  
Reply with quote Back to top
Torby
PostPosted: Jun 04, 2012 - 07:25 PM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

Of course size matters: It's in a Tiny 2313

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
mnehpets
PostPosted: Jun 05, 2012 - 12:00 AM
Hangaround


Joined: Nov 09, 2011
Posts: 399


If you're not using itoa elsewhere, just open code it.

- S

ps: exercise left for the reader: instead of returning the string, print the integer using "putchar()". Rewrite the code to avoid the allocatation of the "s" variable on the stack.

Code:

        char s[6];
        int x = blah;

        s[5] = '\0';
        for (int i = 4; i >= 0; i--) {
                if (x == 0) {
                        s[i] = ' ';
                } else {
                        s[i] = x % 10 + '0';
                        x = x / 10;
                }
        }
 
 View user's profile Send private message  
Reply with quote Back to top
Torby
PostPosted: Jun 07, 2012 - 01:40 AM
Raving lunatic


Joined: Nov 11, 2003
Posts: 3885
Location: Chicago Illinois USA

Oh wow. After a busy weekend when I had no time to spend on it... The whole silly project almost works! Somehow, my "16 character lines" are a character too long.

_________________
Discursive design,

Torby

Some days, it's just not worth chewing through the restraints.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits