Author Topic: C function like printf but not sending to stdout? (XC8)  (Read 30453 times)

0 Members and 1 Guest are viewing this topic.

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
C function like printf but not sending to stdout? (XC8)
« on: March 12, 2013, 01:21:50 am »
Being new to C programming, I just can't seem to figure this one out.

I am sending a string my LCD write function.  The function works fine with variable length text as I use a buffer.

Code: [Select]
void lcd_out(const char *buffer);
Now, how do I send it a formatted string like so?

Code: [Select]
lcd_out("Version %d.%d", verMajor, verMinor);
I need to somehow replicate the behaviour of printf in my function, but how?
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #1 on: March 12, 2013, 01:25:51 am »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #2 on: March 12, 2013, 01:25:57 am »
sprintf will format a string into a buffer. Be very careful of buffer overflow - snprintf prevents this, but is not present in all C libraries.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #3 on: March 12, 2013, 01:54:40 am »
Hmmm... seems I really don't understand how strings and pointers work in C.  I usually program in Delphi and other languages - anything other than C !

How do I:
  • Declare a string (for the LCD buffer)
  • Assign text to that string
  • Pass that to my LCD function
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #4 on: March 12, 2013, 01:57:54 am »
That's because C doesn't have strings. It just has character arrays, and a string literal is just shorthand for a predefined character array. You need to declare a character array "char my_array[length];", you can set its value with strcpy (watch the length!), and you can just pass it by name.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #5 on: March 12, 2013, 02:15:52 am »
Gotcha.  OK, I now have this working:

Code: [Select]
lcd_set_cursor(1,0);
strcpy(lcd_buffer,"My Project");
lcd_out(lcd_buffer);
lcd_set_cursor(2,0);
sprintf(lcd_buffer,"Version %d.%d",version_major,version_minor);
lcd_out(lcd_buffer);

Thanks for your help guys.  Learning a new language can be frustrating at times, but I think I learned a reasonable amount from that.   :)
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #6 on: March 12, 2013, 02:25:41 am »
If you're just printing a constant string, you don't need

Code: [Select]
strcpy(lcd_buffer,"My Project");
lcd_out(lcd_buffer);

You can just use lcd_out("My Project");. Use strcpy if you need to start filling a buffer (then you can use strcat to append).
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Harvs

  • Super Contributor
  • ***
  • Posts: 1161
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #7 on: March 12, 2013, 02:36:17 am »
Keep in mind that the use of some of these type of standard library functions (like printf, sprintf etc.) can be far too heavy for a memory limited uC, so you need to watch your compiled code size.  Possibly the one included with XC8 has been optimized for use in a uC, but often you're better off rolling your own char array manipulation routines for the specific application.  E.g. if you're always just converting an unsigned int to decimal and inserting it at a particular location you can do that with very little memory or processor time.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #8 on: March 12, 2013, 02:53:34 am »
If you're just printing a constant string, you don't need

Code: [Select]
strcpy(lcd_buffer,"My Project");
lcd_out(lcd_buffer);

You can just use lcd_out("My Project");. Use strcpy if you need to start filling a buffer (then you can use strcat to append).

I tried that but get an error:

Code: [Select]
illegal conversion between pointer types
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #9 on: March 12, 2013, 02:55:18 am »
It's been a while, so this is a shot in the dark, but change your lcd_out definition from taking a char * to a char const *.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #10 on: March 12, 2013, 02:59:01 am »
Perfect!  Thanks very much for that.   :)
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1205
  • Country: 00
Re: C function like printf but not sending to stdout? (XC8)
« Reply #11 on: March 12, 2013, 03:00:59 am »
Like Harvs says, the sprintf() library code is going to be pretty chunky due to the fact that it has to support a ton of different formatting options.  In the case of your example it would be more efficient to use the itoa() function to get the integer variables into string format.  If your compiler supports itoa(), that is.  It isn't part of the standard but most compilers support it.

Code: [Select]
.
.
.
lcd_set_cursor(2,0);
lcd_out("Version ");
lcd_out(itoa(version_major, version_buffer, 10)); // 10 == numerical base.
lcd_out(".");
lcd_out(itoa(version_minor, version_buffer, 10));

Just something to keep in mind in case you start running out of program space.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #12 on: March 12, 2013, 03:02:22 am »
When you give a string in quotes, the compiler is free to store it wherever it wants, including in read-only memory, so it will refuse to pass it to a function that can modify it. "char const *" means "pointer to a constant (read-only) character". Some compilers do not enforce this, which is why it didn't occur to me at first.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #13 on: March 12, 2013, 03:03:19 am »
In the case of your example it would be more efficient to use the itoa() function to get the integer variables into string format.  If your compiler supports itoa(), that is.  It isn't part of the standard but most compilers support it.

Good point.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #14 on: March 12, 2013, 03:15:38 am »
Interesting.  The sprintf version adds 569 words of code, while the itoa version only adds 287 words.  Still bloated compared to the assembler I'm used to writing.

On a related point, with assembler I used to convert a simple 0..9 integer to an ASCII character (for display) by adding 0x30 to it.  I assume that sort of thing is also possible in C?
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #15 on: March 12, 2013, 03:17:41 am »
Absolutely. In fact, a char isn't even really a character, it's just an 8-bit integer. You can do math on them directly.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #16 on: March 12, 2013, 03:17:57 am »
Possibly the one included with XC8 has been optimized for use in a uC,

One of the features of the (ex) Hi-Tech compilers is 'omniscient code generation' which effectively compiles the entire program and used libraries as a single module. That gives the optimiser visibility of the entire program allowing it to remove redundant code. I suspect they jump through additional hoops with the printf series parsing possible format strings to know what is redundant.

With the free version you only get messages telling you how much better the paid for one would be. Some claim the free version deliberately generates horrid code, personally I think it is just an indication of how much work the optimiser is expected to do.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #17 on: March 12, 2013, 03:19:04 am »
On a related point, with assembler I used to convert a simple 0..9 integer to an ASCII character (for display) by adding 0x30 to it.  I assume that sort of thing is also possible in C?

yep, that still works fine.
As said above, a char is just an 8 bit number. So you can do maths on them however you want.
« Last Edit: March 12, 2013, 03:21:43 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #18 on: March 12, 2013, 03:22:22 am »
People keep telling me how C code is so much quicker to write than assembler, but I'm old (actually middle age!) and have been somewhat set in my ways.

I'm sure I'll get better at writing C code, but it's painfully slow at present.

I've been pondering whether the standard or pro version of XC8 would be the way to go.  Code space it probably not so much of an issue, but some projects I do use DMX and some high speed SPI data streaming so speed of execution can be important.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #19 on: March 12, 2013, 03:25:49 am »
People keep telling me how C code is so much quicker to write than assembler, but I'm old (actually middle age!) and have been somewhat set in my ways.

I can bang out PIC assembly pretty fast. I rarely revert to C on an 8-bit micro, though I do use it for the 16- and 32-bit ones.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #20 on: March 12, 2013, 03:26:59 am »
Interesting.  The sprintf version adds 569 words of code, while the itoa version only adds 287 words.  Still bloated compared to the assembler I'm used to writing.

On a related point, with assembler I used to convert a simple 0..9 integer to an ASCII character (for display) by adding 0x30 to it.  I assume that sort of thing is also possible in C?

Sure. Something like this:

Code: [Select]
    int versionMajor = 1;
    int versionMinor = 5;

    char buf[] = "Version x.y";

    buf[8] = versionMajor + 0x30;
    buf[10] = versionMinor + 0x30;
I'm not an EE--what am I doing here?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #21 on: March 12, 2013, 03:29:22 am »
This works:

Code: [Select]
char temp;
temp = version_major+0x30;
lcd_out(&temp);

But this doesn't:

Code: [Select]
lcd_out(version_major+0x30);
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #22 on: March 12, 2013, 03:30:53 am »
Interesting.  The sprintf version adds 569 words of code, while the itoa version only adds 287 words.  Still bloated compared to the assembler I'm used to writing.

On a related point, with assembler I used to convert a simple 0..9 integer to an ASCII character (for display) by adding 0x30 to it.  I assume that sort of thing is also possible in C?

Sure. Something like this:

Code: [Select]
    int versionMajor = 1;
    int versionMinor = 5;

    char buf[] = "Version x.y";

    buf[8] = versionMajor + 0x30;
    buf[10] = versionMinor + 0x30;

Ooh... I like that.  Using the array as ... well an array!
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #23 on: March 12, 2013, 03:31:36 am »
I vastly prefer using '0' to 0x30 in that case - more obvious.

(As an aside, it's also "portable", as in "back when C was designed not everything was ASCII", but that's kind of like buying a trailer for your pickup truck that is also horse-compatible...)

This works:

Code: [Select]
char temp;
temp = version_major+0x30;
lcd_out(&temp);

But this doesn't:

Code: [Select]
lcd_out(version_major+0x30);

Like I said, a char is just a number. You've got to put it in a string/array. If you're doing it a lot of times and can spare the space for code, it may be more efficient to make a second function that just takes a single char.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #24 on: March 12, 2013, 03:32:09 am »
But this doesn't:

Code: [Select]
lcd_out(version_major+0x30);

No; the lcd_out function is expecting the address of a character array in memory. The expression (version_major+0x30) is not a memory address it is an immediate value. Note that whenever you pass a string like "foo" into a function you are really passing the memory address of the first character 'f'.
I'm not an EE--what am I doing here?
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #25 on: March 12, 2013, 03:34:35 am »
Code: [Select]
lcd_out(&temp);

Ooh, missed this one. Bad, very bad. You're taking the address of the char to use it like a pointer. The problem is that C strings contain an end-of-string marker one past the last character, which doesn't exist because this is just a single char variable, so it's looking somewhere in God-knows-where in your memory for it. You got lucky.

The worst part is that there is absolutely no way for the compiler to detect it. A memory analyzer like Valgrind would scream bloody murder at the sight of it, but you can't exactly use Valgrind on an 8-bit microcontroller.
« Last Edit: March 12, 2013, 03:37:07 am by c4757p »
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #26 on: March 12, 2013, 03:36:56 am »
I vastly prefer using '0' to 0x30 in that case - more obvious.

Good point. I was going with 0x30 because that is what was given, but the improved version would look like this:

Code: [Select]
    int versionMajor = 1;
    int versionMinor = 5;

    char buf[] = "Version x.y";

    buf[8] = '0' + versionMajor;
    buf[10] = '0' + versionMinor;

(Note the single quotes around the '0', not double quotes. The single quotes turn the character into its ASCII value.)
I'm not an EE--what am I doing here?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #27 on: March 12, 2013, 03:38:48 am »
Doing it this way:

Code: [Select]
strcpy(lcd_buffer,"Version x.y");
lcd_buffer[8] = version_major + 0x30;
lcd_buffer[10] = version_minor + 0x30;
lcd_out(lcd_buffer);

Results in no real code bloat at all.

 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #28 on: March 12, 2013, 03:40:06 am »
Ooh, missed this one. Bad, very bad.

Yup, good catch.

The string "hello" is stored in memory as the byte sequence ('h', 'e', 'l', 'l', 'o', 0x00). The null byte is the end of string marker. String functions like lcd_out() or printf() look for this marker so they know when to stop. If you build your own character arrays you must make sure to put the null byte after the last position (many library routines like strcpy do this for you automatically, but watch out for the exceptions).
I'm not an EE--what am I doing here?
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #29 on: March 12, 2013, 03:42:37 am »
If you're writing to a LCD panel it will be a fixed number of characters anyway.
So you could use a fixed length array of char.

Then you don't have to worry about lengths
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #30 on: March 12, 2013, 03:45:24 am »
Even more efficient:

Code: [Select]
lcd_outstr("Version ");
lcd_char(version_major + 0x30);
lcd_char('.');
lcd_char(version_minor + 0x30);
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #31 on: March 12, 2013, 03:47:46 am »
If you're writing to a LCD panel it will be a fixed number of characters anyway.
So you could use a fixed length array of char.

Then you don't have to worry about lengths

I have declared the lcd_buffer as:

Code: [Select]
unsigned char lcd_buffer[17];
As I assumed I needed the extra byte for the null terminator in addition to the actual 16 characters (max) for the display.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #32 on: March 12, 2013, 03:51:50 am »
yeah, if you want to manipulate it with the C string handling routenes you need the null on the end.
But you dont "have" to use those.

Since its just an array of numbers (like in delphi.. var lcd_buffer[16] : byte; ), you can do stuff to it directly as ascii numbers.
etc. you can copy or set the individual character positions, or the entire array using memcpy/memset and then you dont need the null and you don't get any overhead from the string funtions
« Last Edit: March 12, 2013, 03:58:21 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #33 on: March 12, 2013, 03:53:38 am »
If I were using a character array to represent a "physical character array", I'd probably treat it like a true array rather than a string and skip the null. Can't really see why I would need to use string functions on something like that anyway.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #34 on: March 12, 2013, 03:57:26 am »
My lcd output routine was adapted from something I found on the 'net:

Code: [Select]
void lcd_outstr(const char *buffer)
{
while(*buffer)              // Write data to LCD up to null
{
    lcd_char(*buffer); // Write character to LCD
    buffer++;               // Increment buffer
}
}

Does that make sense with the method of calling it?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #35 on: March 12, 2013, 04:00:05 am »
Whenever I start learning a new programming language I usually write butt-ugly code to start with and improve (optimise) it with practice.

I'm not new to the concept of pointers, bytes, etc but was failing to recognise them in the C context.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #36 on: March 12, 2013, 04:00:29 am »
Looks fine to me. And thank you thank you thank you for not using the old lcd_char(*buffer++) trick. (Hopefully I didn't give anyone any ideas...  :))

This might be a bit more conventional, though:
Code: [Select]
for ( ; *buffer; ++buffer) {
    lcd_char (*buffer);
}

(Yes, you can skip a section of the for-loop definitions. Just omit it and leave the semicolon.)
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #37 on: March 12, 2013, 04:04:51 am »
Personally, i would forget pointers until you become familiar with C coding in general.
They tend to complicate things and its real easy to make mistakes.

You can make any program you want without having to use them.
They just make some things faster and quicker to code, since you can pass the memory address instead of the actual data
« Last Edit: March 12, 2013, 04:07:32 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #38 on: March 12, 2013, 04:07:05 am »
I think I'm on the right track now thanks to you guys.

One more question; If there is only one statement to execute in the for loop, are the braces around that statement still required?
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #39 on: March 12, 2013, 04:08:15 am »
Yeah, they do complicate things, but you can't really do much at all without them in C...

I think I'm on the right track now thanks to you guys.

One more question; If there is only one statement to execute in the for loop, are the braces around that statement still required?

Nope. I tend to use them because they save rearranging stuff if I need them later. Also, if your editor doesn't auto-indent, omitting them can be a recipe for disaster, but the ones I use all do.

The technical explanation is that the contents of the loop is just one statement and no braces, and the braces and their own contents count collectively as one statement. You can also use them on their own, but that's not very useful.
« Last Edit: March 12, 2013, 04:10:13 am by c4757p »
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #40 on: March 12, 2013, 04:09:18 am »
I think I'm on the right track now thanks to you guys.

One more question; If there is only one statement to execute in the for loop, are the braces around that statement still required?

nope, you only need the braces for multiple statements.

for (i=0;i<=10;i++)  myfunction();
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #41 on: March 12, 2013, 04:10:20 am »
Cool.  I thought the same "block rules" applied to C as I use in Delphi, etc (and it seemed to work) but thought I'd ask to be sure.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #42 on: March 12, 2013, 04:14:10 am »
Delphi is Pascal, right? I haven't touched Pascal in ages, but I remember finding it strikingly similar to C.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7369
  • Country: nz
Re: C function like printf but not sending to stdout? (XC8)
« Reply #43 on: March 12, 2013, 04:16:36 am »
On the subject of braces(blocks)

Sometimes you may need to use them inside a case statement.

You can't declare a new variable inside a case statement unless its inside a block.

Code: [Select]
Switch (foo)
{
  case 1:
       char mychar;    <- doesnt work (you can't declare a new variable)
       mychar=5;
  break;
  case 2:
  {
       char mychar2;   <- works fine
       mychar2 = 10;
       break;
  }
}
However, since your used to Delphi (like me) its unlikely you'll ever want to declare variables in the middle of code.
It can be useful though, your case statement might be based on the mode your device is in. Some modes might need lots of math done and require many variables be declared which are not needed in other modes.
« Last Edit: March 12, 2013, 04:21:35 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #44 on: March 12, 2013, 04:16:42 am »
This might be a bit more conventional, though:
Code: [Select]
for ( ; *buffer; ++buffer) {
    lcd_char (*buffer);
}

Danger, Will Robinson! This code explicitly assumes that the array of characters in buffer is null terminated. Given earlier comments about the possible omission of the terminator when using 16 byte fixed length arrays, this code snippet could lead to disaster...
I'm not an EE--what am I doing here?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #45 on: March 12, 2013, 04:23:46 am »
This might be a bit more conventional, though:
Code: [Select]
for ( ; *buffer; ++buffer) {
    lcd_char (*buffer);
}

Danger, Will Robinson! This code explicitly assumes that the array of characters in buffer is null terminated. Given earlier comments about the possible omission of the terminator when using 16 byte fixed length arrays, this code snippet could lead to disaster...

Been thinking of including a max length check into the loop, but still pondering how.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #46 on: March 12, 2013, 04:47:36 am »
Been thinking of including a max length check into the loop, but still pondering how.

That's easy. Something like this:

Code: [Select]
#define LCD_BUFFER_SIZE 16

void lcd_outstr(const char *buffer)
{
    const char *end = buffer + LCD_BUFFER_SIZE;

    for ( ; buffer < end && *buffer; ++buffer) {
        lcd_char (*buffer);
}
I'm not an EE--what am I doing here?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #47 on: March 12, 2013, 04:51:23 am »
Ah, you beat me to it.  I almost had it working but was looking up the AND operator.  ;D
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #48 on: March 12, 2013, 05:14:56 am »
Danger, Will Robinson! This code explicitly assumes that the array of characters in buffer is null terminated. Given earlier comments about the possible omission of the terminator when using 16 byte fixed length arrays, this code snippet could lead to disaster...

True, I was just working with what he already had. If I were treating it like an array I would use a normal length-bounded array iteration. Didn't notice the inconsistency.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #49 on: March 12, 2013, 06:19:23 am »
I need to somehow replicate the behaviour of printf in my function, but how?

Code: [Select]
#include <stdarg.h>
#include <stdio.h>

// returns number of characters printed
int lcd_printf(const char *format, ...) {
  va_list args;
  int count;
  char buffer[100]; // pick a reasonable size

  va_start(args, format);
  count = vsnprintf(buffer, sizeof(buffer), format, args);
  va_end(args);

  const char *p = buffer;
  while (*p) lcd_char(*p++);

  return count;
}

PS. Not guaranteed to work on rinky-dink development systems. ;-)
PPS. Does your lcd_char() handle CR and LF correctly?
« Last Edit: March 12, 2013, 06:21:20 am by andyturk »
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1077
  • Country: fi
Re: C function like printf but not sending to stdout? (XC8)
« Reply #50 on: March 12, 2013, 07:45:56 am »
Note that if you're not using printf for anything you can override the putch() function to redirect the output somewhere else.

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #51 on: March 12, 2013, 08:49:39 am »
I will be using serial comms in due course, but that's good to know anyway.
 

Offline dfnr2

  • Regular Contributor
  • *
  • Posts: 228
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #52 on: March 12, 2013, 06:53:21 pm »
To answer your original question, there is no stdout.  the printf() function you get with xc8 calls putch(), which you can define.  So if you rename your lcd_char() function to putch(), then calling printf will print to the lcd.

Having said that, printf() is usually not used with these tiny chips.  You can put it in if you have lots of space, but as people have indicated, writing your own number->string functions is much more efficient.  For what you're doing, copying strings, etc. is unwarranted, and way too busy.  Better to have little routines tailored to your output.  For example, for an 8-bit unsigned, you could use a dedicated routine such as print_dec_8(uint8), like so:

uint8 val;
val = some_stuff();
lcd_print("The number is: ");
lcd_print_dec_8(val);
...

Code: [Select]
/* PROCEDURE:lcd_print_dec_u8
 * INPUTS: val (uint8): 8-bit unsigned value to be printed
 * OUTPUTS: none
 *
 * DESCRIPTION: Prints argument, in decimal, to the serial port, using
 * lcd_char().
 */
void lcd_print_dec_u8(uint8 val)
{
    uint8 hundreds = 0;
   
    /* If > 100, only two choices for most sig digit. */
    if (val >= 200) {
        hundreds = 2;
        val = val - 200;
        lcd_char('2');
    } else if (val >= 100) {
        hundreds = 1;
        val = val - 100;
        lcd_char('1');
    }

    /* calculate the tens digit, if present, and print.*/
    if ((0 != hundreds) || (val >= 10)) {
        uint8 tens = 0;

        while (val >= 10) {
            val -= 10;
            tens++;
        }
        lcd_char(tens + '0');
    }

    lcd_char(val + '0');
}

« Last Edit: March 12, 2013, 06:58:05 pm by dfnr2 »
 

Offline andersm

  • Super Contributor
  • ***
  • Posts: 1077
  • Country: fi
Re: C function like printf but not sending to stdout? (XC8)
« Reply #53 on: March 12, 2013, 08:37:57 pm »
The XC8 compiler will actually generate an optimized printf based on the format strings used, so the results should be more compact than a typical library implementation. Doing the work manually may still be more efficient, but it depends on usage.

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #54 on: March 12, 2013, 10:58:33 pm »
... writing your own number->string functions is much more efficient.  For what you're doing, copying strings, etc. is unwarranted, and way too busy.  Better to have little routines tailored to your output...
Pardon me, but: Yuck.

Re-inventing the wheel and all that.
 

Offline grumpydoc

  • Super Contributor
  • ***
  • Posts: 2682
  • Country: gb
Re: C function like printf but not sending to stdout? (XC8)
« Reply #55 on: March 12, 2013, 11:02:37 pm »
Quote
Re-inventing the wheel and all that.

Agree, and once you've called (v)(s)(n)printf a few times the overhead will start to look cheap given the convenience.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #56 on: March 12, 2013, 11:31:33 pm »
Quote
Re-inventing the wheel and all that.

Agree, and once you've called (v)(s)(n)printf a few times the overhead will start to look cheap given the convenience.
Touché.
 

Offline melonstorm

  • Contributor
  • Posts: 7
  • Country: ../cake
  • Becomes 200% fluffier when statically charged!
Re: C function like printf but not sending to stdout? (XC8)
« Reply #57 on: March 13, 2013, 09:06:27 pm »
There are also size-reduced implementations of (s)printf available, like this LGPL-licensed one. If you need sprintf in your project and don't want to use the standard library's comparatively large implementation, you could choose to use something like this.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #58 on: April 15, 2013, 05:21:49 am »
My next issue is not getting the leading zeros like I though this would:

Code: [Select]
sprintf(lcd_buffer,"%3d",sw_result);
I thought this should give me a string "000" ... "255", but it seems to still be "0" ... "255" (no leading zeros).
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #59 on: April 15, 2013, 05:32:31 am »
My next issue is not getting the leading zeros like I though this would:

Code: [Select]
sprintf(lcd_buffer,"%3d",sw_result);
I thought this should give me a string "000" ... "255", but it seems to still be "0" ... "255" (no leading zeros).

Have you tried "%3.3d" as the format string?
I'm not an EE--what am I doing here?
 

Offline ecat

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: gb
Re: C function like printf but not sending to stdout? (XC8)
« Reply #60 on: April 15, 2013, 05:38:22 am »
Some printf implementations provide only limited options, still the format specifier for 001, 002 etc is "%03d"

printf("%03d", 5);

Should result in 005



 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #61 on: April 15, 2013, 05:39:55 am »
My next issue is not getting the leading zeros like I though this would:

Code: [Select]
sprintf(lcd_buffer,"%3d",sw_result);
I thought this should give me a string "000" ... "255", but it seems to still be "0" ... "255" (no leading zeros).

Have you tried "%3.3d" as the format string?

Ah, that's got it.  I read the XC8 (and other) docs several times and didn't understand that was how it worked.  Thanks.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #62 on: April 15, 2013, 05:40:35 am »
Some printf implementations provide only limited options, still the format specifier for 001, 002 etc is "%03d"

printf("%03d", 5);

Should result in 005

Should, but doesn't for some reason.  The "%3.3d" does work however.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #63 on: May 11, 2013, 12:09:18 am »
People keep telling me how C code is so much quicker to write than assembler, but I'm old (actually middle age!) and have been somewhat set in my ways.

I'm sure I'll get better at writing C code, but it's painfully slow at present.

I've been pondering whether the standard or pro version of XC8 would be the way to go.  Code space it probably not so much of an issue, but some projects I do use DMX and some high speed SPI data streaming so speed of execution can be important.

David, yeah it is worth the trouble.  C is a great language to develop program with.  Do watch out, with C, it doesn't protect you against yourself.

To quote someone: "If it is absolutely dummy proof, it would be in a form only absolute dummy will use."

With C, it is not dummy proof, you have to watch you are doing, but it let you do what you want to do and assumes you really know what you are doing.

Rick
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #64 on: May 11, 2013, 12:34:23 am »
My lcd output routine was adapted from something I found on the 'net:

Code: [Select]
void lcd_outstr(const char *buffer)
{
while(*buffer)              // Write data to LCD up to null
{
    lcd_char(*buffer); // Write character to LCD
    buffer++;               // Increment buffer
}
}

Does that make sense with the method of calling it?

David_AVD,

Using this as an opportunity to show you why C is powerful but you have to watch out.

First, incase you don’t know the two cases of using ++.
int   counter=0;
int   another;

another = ++counter;  // here counter is incremented before assigning to variable
another = counter++; // here counter is incremented after assigning to variable

The while() statement you have does not check buffer size.  A better implementation is:

void lcd_outstr(const char *buffer)
{
int   ii=0;
int   maxSize=100;  // hard coded max, but can be parameter driven
   while(*buffer && ++ii<maxSize)   // Write upto terminator or maxSize bytes of data to LCD
   {
       lcd_char(*buffer);       // Write character to LCD
       buffer++;               // Increment buffer
   }
}

I added a counter so if a proper string terminator is NOT found, it will not output more than 100 characters.  Lacking the counter and if the string is not properly terminated, it will just keep printing until the CPU hangs or when other bad things happens.

Also, I never use single character variables.  If you have “int i;”, generic string search is useless.  You will find tons of ‘i’ unless you use full word/variable-name type of search.  If you use ‘ii’ or ‘jj’ or ‘zz’, they are much easier to find.

Rick
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #65 on: May 11, 2013, 12:52:07 am »
Good stuff Rick.  Thanks.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #66 on: May 11, 2013, 12:57:30 am »
I think I'm on the right track now thanks to you guys.

One more question; If there is only one statement to execute in the for loop, are the braces around that statement still required?

David_AVD,

c4757p already pointed out that you don't really need the { } except for multiple statements.  An additional useful technique is comma which continues the calculation statement.  When comma is used, the last statement has the final value and that is used.
ii = 1, 2, 3, 4 ;   // ii is assigned 4, the last evaluation done

original:
while (*buffer) {
    lcd_char(*buffer);
    buffer++;
}


another version with comma to make that one statement:
while (*buffer) lcd_char(*buffer), buffer++;

another version with for ( ; ; )
for ( ;*buffer; lcd_char(*buffer), ++buffer ) ;
Explaination
for ( ; // this first semicolon with stuff between ( ; means no initialization needed
for ( ; *buffer;  // between the first and second semicolon is the condition to
                      // remain looping, so here is checking to see if current buffer char is
                      // not null before continue loop
for ( ;*buffer; lcd_char(*buffer), ++buffer )
                     // after the last semicolon, there is the end of a loop closing statement
                     // before end of the loop, do the lcd_char.  Since it is a comma, it continue
                     // the calculation and do the buffer pointer increment to point at the next char
for ( ;*buffer; lcd_char(*buffer), ++buffer ) ;
                     // the semicolon after the ) saids I have an empty statement
                     // there is nothing to left to do


Now one with size limit:

int  ii,newSize;
for (ii=0, newSize=100 ; *buffer & ii<newSize; ii++, lcd_char(*buffer), ++buffer);

I leave it for you to figure out the intialization, the continue-loop checking, and the loop end check.

Good luck with your C learning.  It will be a fun ride.

By the way, note this joke, it highlights some C programming facts:

When a C programmer brought a dozen eggs, how many eggs did he just buy?
The answer is 11.

0 , 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11
Only 11.  C programmer always start counting with zero.

Rick
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #67 on: May 11, 2013, 02:02:18 am »

c4757p already pointed out that you don't really need the { } except for multiple statements.  An additional useful technique is comma which continues the calculation statement.

I have been writing C for nearly 30 years and don't remember the last time I used a comma operator. I might have kludged an extra assignment into a for statement or macro using it but I can't think of an example. It is hardly useful.

I would recommend keeping braces around single statements because a consistent format is easier to read and forgetting to add braces if you add another statement screws up so badly without looking obvious.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #68 on: May 11, 2013, 02:10:38 am »
The only use that I can see for a comma operator is combining expressions in a for loop. (I wouldn't really call it a kludge. I've seen some very clear and elegant uses of that to emulate more sophisticated looping systems like in higher-level languages, and they didn't seem kludgey at all.) The only other use I can think of for the comma operator is intentional obfuscation.

I would recommend keeping braces around single statements because a consistent format is easier to read and forgetting to add braces if you add another statement screws up so badly without looking obvious.

I disagree. If it doesn't look obvious when you forget to add braces you need to use a better editor. There's nothing wrong with doing it if you find that it makes future extension easier, but I often find myself making enough single-statement blocks that it saves me more time to omit them than otherwise. Obviously, the time saved either way is minuscule.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline megajocke

  • Regular Contributor
  • *
  • Posts: 185
  • Country: 00
Re: C function like printf but not sending to stdout? (XC8)
« Reply #69 on: May 11, 2013, 02:19:06 am »
An additional useful technique is comma which continues the calculation statement.  When comma is used, the last statement has the final value and that is used.
ii = 1, 2, 3, 4 ;   // ii is assigned 4, the last evaluation done

Actually, that's not the result. Assignment has higher precedence than the comma operator, so this is the same as doing:

(ii = 1), 2, 3, 4 ;

which has the result that ii is assigned the value of 1, whereafter the expressions 2, 3 and 4 are evaluated with the results being thrown away, essentially becoming no-ops. The compiler might give you a warning that you have expressions without side effects if compiling this code.

However, if you write

ii = (1, 2, 3, 4) ;

you get the result claimed before.
« Last Edit: May 11, 2013, 02:22:07 am by megajocke »
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #70 on: May 11, 2013, 02:37:41 am »
I disagree. If it doesn't look obvious when you forget to add braces you need to use a better editor. There's nothing wrong with doing it if you find that it makes future extension easier, but I often find myself making enough single-statement blocks that it saves me more time to omit them than otherwise. Obviously, the time saved either way is minuscule.

My editor of choice adds braces as I type so I would have to delete them for single statements. Time is insignificant, screen space less so but I value consistent appearance over space.

As for for loops they are just shorthand for a commonly used form of while statement, kludging less common forms of while into them with comma operators is more confusing than just using while.
 

Offline glatocha

  • Regular Contributor
  • *
  • Posts: 109
Re: C function like printf but not sending to stdout? (XC8)
« Reply #71 on: May 11, 2013, 03:01:39 am »
I am always scared to use library functions.
They might cover much more than I need and cause a high memory usage.
I prepare most of my routines on myself. For example for LCD Integer display:

Code: [Select]
void LCD_Int(int16_t num)
{
    int16_t div;
    uint16_t i;
    if (num <0)
    {
        LCD_SendCHAR_4b('-');
        num = num * -1;
    }
    for (i=10000;i>=10;i=i/10)
    {
        if (num>=i)
        {
            div = num/i;
            num = num%i;
            LCD_SendCHAR_4b(div + '0');
        }
    }
    LCD_SendCHAR_4b(num + '0');
}

Same I have for doubles.
I am also planning to rewrite most of it in asm and maybe get rid of dividing.

I started programming with atmel 2051 with 2kb Flash and 128 RAM bytes. So still have in mind always optimize.
But maybe nowadays much cheaper is to just update the chip with higher memory version of 0,10$.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #72 on: May 11, 2013, 03:08:23 am »
As for for loops they are just shorthand for a commonly used form of while statement, kludging less common forms of while into them with comma operators is more confusing than just using while.

I've always seen a "for" loop as being iterative over a sequence, and a "while" loop as being repetitive conditional on an external state - for example, while the input given is invalid, continue giving an error message and requesting it again. I'd rather use a "for" loop to loop over some sort of container, even if the top of the loop is a little bit ugly, as it makes the intention clear.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #73 on: May 11, 2013, 03:12:04 am »
void lcd_outstr(const char *buffer)
{
int   ii=0;
int   maxSize=100;  // hard coded max, but can be parameter driven
   while(*buffer && ++ii<maxSize)   // Write upto terminator or maxSize bytes of data to LCD
   {
       lcd_char(*buffer);       // Write character to LCD
       buffer++;               // Increment buffer
   }
}

A good practice when writing code is to replay the code in your mind and see if it does what you think it ought to do.

In the above example, suppose the buffer has size 1 (a thought experiment). What will happen?

First pass through the loop: buffer points to the one and only character so the while() test is successful and the character is printed.

Second pass through the loop: buffer was incremented and now points beyond the end of the buffer. It will print some unknown character to the LCD.

Note how the ++ii<maxSize test will not save it, since the && operator short circuits and if the first condition is true the second condition will never be evaluated. If this logic fails with a buffer of size 1, it will fail with a buffer of size 100.

Another goal of good code is to be clear and readable, so that human readers who encounter the code later on are readily able to understand what it is intended to do.  In light of that, I suggest this variant:

Code: [Select]
void lcd_outstr(const char *buffer, int buflen)
{
const char *endbuf = buffer + buflen;
while(buffer < endbuf && *buffer)
{
    lcd_char(*buffer);
    ++buffer;
}
}
I'm not an EE--what am I doing here?
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #74 on: May 11, 2013, 03:23:21 am »
And I would suggest this variant:

Code: [Select]
void lcd_outstr(const char *buffer, size_t buflen)
{
size_t i;
        for (i = 0; i < buflen && buffer[i]; ++i) {
                lcd_char (buffer[i]);
        }
}

Or if you're tight on RAM in a microcontroller application, slightly less readable but saving a variable (that the compiler ought to optimize out anyway, but some compilers suck):
Code: [Select]
void lcd_outstr(const char *buffer, size_t buflen)
{
        for (i = 0; buflen && *buffer; ++buffer, --buflen) {
                lcd_char (*buffer);
        }
}

I wouldn't really recommend the second one, but it's not awful, I suppose.
« Last Edit: May 11, 2013, 03:24:59 am by c4757p »
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #75 on: May 11, 2013, 03:34:54 am »
An additional useful technique is comma which continues the calculation statement.  When comma is used, the last statement has the final value and that is used.
ii = 1, 2, 3, 4 ;   // ii is assigned 4, the last evaluation done

Actually, that's not the result. Assignment has higher precedence than the comma operator, so this is the same as doing:

(ii = 1), 2, 3, 4 ;

which has the result that ii is assigned the value of 1, whereafter the expressions 2, 3 and 4 are evaluated with the results being thrown away, essentially becoming no-ops. The compiler might give you a warning that you have expressions without side effects if compiling this code.

However, if you write

ii = (1, 2, 3, 4) ;

you get the result claimed before.

Yup, you are right...  Forgot about the () there.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #76 on: May 11, 2013, 03:37:14 am »
void lcd_outstr(const char *buffer)
{
int   ii=0;
int   maxSize=100;  // hard coded max, but can be parameter driven
   while(*buffer && ++ii<maxSize)   // Write upto terminator or maxSize bytes of data to LCD
   {
       lcd_char(*buffer);       // Write character to LCD
       buffer++;               // Increment buffer
   }
}

A good practice when writing code is to replay the code in your mind and see if it does what you think it ought to do.

In the above example, suppose the buffer has size 1 (a thought experiment). What will happen?

First pass through the loop: buffer points to the one and only character so the while() test is successful and the character is printed.

Second pass through the loop: buffer was incremented and now points beyond the end of the buffer. It will print some unknown character to the LCD.

Note how the ++ii<maxSize test will not save it, since the && operator short circuits and if the first condition is true the second condition will never be evaluated. If this logic fails with a buffer of size 1, it will fail with a buffer of size 100.


Good pick.  Goes to show, a quick line of code merely to show a point should still be carefully reviewed.

Edit:
Edited the quote to just keep the part my "Good pick" was referring to.  The other point I did not agreed (which is in another comment that I just made).
« Last Edit: May 11, 2013, 04:10:03 am by Rick Law »
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #77 on: May 11, 2013, 03:43:44 am »
void lcd_outstr(const char *buffer)
{
int   ii=0;
int   maxSize=100;  // hard coded max, but can be parameter driven
   while(*buffer && ++ii<maxSize)   // Write upto terminator or maxSize bytes of data to LCD
   {
       lcd_char(*buffer);       // Write character to LCD
       buffer++;               // Increment buffer
   }
}

A good practice when writing code is to replay the code in your mind and see if it does what you think it ought to do.

In the above example, suppose the buffer has size 1 (a thought experiment). What will happen?

Like most string functions it is intended to output zero terminated strings. The buffer has no size. The string size is from the start of the buffer to where ever the zero terminator is. The maxSize check is to prevent overflow of the LCD (which may or may not be required).
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #78 on: May 11, 2013, 03:51:40 am »
As for for loops they are just shorthand for a commonly used form of while statement, kludging less common forms of while into them with comma operators is more confusing than just using while.

I've always seen a "for" loop as being iterative over a sequence, and a "while" loop as being repetitive conditional on an external state - for example, while the input given is invalid, continue giving an error message and requesting it again. I'd rather use a "for" loop to loop over some sort of container, even if the top of the loop is a little bit ugly, as it makes the intention clear.

I use for over while out of habit.  Prior to optimization compilers, I read that for( ; ; ) is far more efficient over while(1).  After confirming it by looking at the op codes actually generated, I confirmed that for my compiler do indeed generate much better code with for( ; ; ) over while(1).

Where I am doing a single task within the loop, I found the comma-inside-for much easier to read.  Single (or very simple) looped task such as scanning for a particular case.

for (cp=startOfSomething,kp=endOfSomething;TestForEnd(cp);callthis(),prepareToReLoop) ;

Another case where I would use comma is to seperate substeps:
   thisOne=(thatOne++,firstFunction(&thatOne));

A matter of style and habit, I suppose.
« Last Edit: May 11, 2013, 05:01:07 am by Rick Law »
 

Offline kfitch42

  • Frequent Contributor
  • **
  • Posts: 300
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #79 on: May 11, 2013, 03:53:24 am »
sprintf will format a string into a buffer. Be very careful of buffer overflow - snprintf prevents this, but is not present in all C libraries.

snprintf helps, but it does not absolve you from buffer related bugs. The biggest problem with snprintf is that it DOES NOT guarantee null-termination. If it ends up truncating (to avoid buffer overflow) the buffer will not be null-terminated. it is the responsibility of the caller of snprintf to check the return value and take appropriate action in case of truncation. In reality, most coders forget this.

P.S. I can't count the number of times I have seen off-by-one-errors when using snprintf and friends...
« Last Edit: May 11, 2013, 03:57:06 am by kfitch42 »
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #80 on: May 11, 2013, 03:59:29 am »
Code: [Select]
void lcd_outstr(const char *buffer, int buflen)
{
const char *endbuf = buffer + buflen;
while(buffer < endbuf && *buffer)
{
    lcd_char(*buffer);
    ++buffer;
}
}

A matter of style and system.  Pointer arithmetic makes the code difficult to port.  I started coding C when pointers could be 12 bits (crazy segment:offset of the 8088/8086), 16 bits, or 32 bits.  Once you do pointer arithmetic, you are relying on certain method of type-conversion.

When I do an int as a counter, int is defined as system default word size.  It was 8 bit signed with my first C compiler, 16 later, then 32.  When I am counting something up to just 100, using an int will cause less portability issues in my experience.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #81 on: May 11, 2013, 04:06:46 am »
And I would suggest this variant:

Code: [Select]
void lcd_outstr(const char *buffer, size_t buflen)
{
size_t i;
        for (i = 0; i < buflen && buffer[i]; ++i) {
                lcd_char (buffer[i]);
        }
}

Or if you're tight on RAM in a microcontroller application, slightly less readable but saving a variable (that the compiler ought to optimize out anyway, but some compilers suck):
Code: [Select]
void lcd_outstr(const char *buffer, size_t buflen)
{
        for (i = 0; buflen && *buffer; ++buffer, --buflen) {
                lcd_char (*buffer);
        }
}

I wouldn't really recommend the second one, but it's not awful, I suppose.

I generally prefer to use *buffer with buffer++ over buffer with i++.  Another style and taste thing.

I think we are either going to scare David_AVD from coding C pretty soon showing him a million way to skin a cat, or he is going to get very excited to try coming up with his million&1 way to skin the cat.
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #82 on: May 11, 2013, 04:11:20 am »
Code: [Select]
void lcd_outstr(const char *buffer, int buflen)
{
const char *endbuf = buffer + buflen;
while(buffer < endbuf && *buffer)
{
    lcd_char(*buffer);
    ++buffer;
}
}

A matter of style and system.  Pointer arithmetic makes the code difficult to port.  I started coding C when pointers could be 12 bits (crazy segment:offset of the 8088/8086), 16 bits, or 32 bits.  Once you do pointer arithmetic, you are relying on certain method of type-conversion.

When I do an int as a counter, int is defined as system default word size.  It was 8 bit signed with my first C compiler, 16 later, then 32.  When I am counting something up to just 100, using an int will cause less portability issues in my experience.
This code is more stylish and will run much faster (apparently)...
Code: [Select]
void lcd_outstr(const char *buffer, int buflen) {
   const char *endbuf;
   for(endbuf=buffer+buflen;buffer<endbuf&&*buffer;lcd_char(*buffer),++buffer);
}
 

Offline glatocha

  • Regular Contributor
  • *
  • Posts: 109
Re: C function like printf but not sending to stdout? (XC8)
« Reply #83 on: May 11, 2013, 04:14:19 am »
My God. In which way it is more stylish?
That's why I don't like C. The fight for putting as less code as possible.
Somehow it always takes my much more time to think what I want to write then typing itself. So I don't really care how small the source code is. I would rather prefer more easy reading.
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #84 on: May 11, 2013, 04:19:52 am »
My God. In which way it is more stylish?

In the way that it takes the piss out of some of the other posts in this thread :)
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #85 on: May 11, 2013, 04:22:43 am »
If you want to make a real piss-taking abomination you have to use the unholy combination *buffer++.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Rufus

  • Super Contributor
  • ***
  • Posts: 2094
Re: C function like printf but not sending to stdout? (XC8)
« Reply #86 on: May 11, 2013, 04:25:03 am »
If you want to make a real piss-taking abomination you have to use the unholy combination *buffer++.

But then it wouldn't need a comma operator :(
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #87 on: May 11, 2013, 04:28:29 am »
Code: [Select]
void lcd_outstr(const char *buffer, int buflen)
{
const char *endbuf = buffer + buflen;
while(buffer < endbuf && *buffer)
{
    lcd_char(*buffer);
    ++buffer;
}
}

A matter of style and system.  Pointer arithmetic makes the code difficult to port.  I started coding C when pointers could be 12 bits (crazy segment:offset of the 8088/8086), 16 bits, or 32 bits.  Once you do pointer arithmetic, you are relying on certain method of type-conversion.

When I do an int as a counter, int is defined as system default word size.  It was 8 bit signed with my first C compiler, 16 later, then 32.  When I am counting something up to just 100, using an int will cause less portability issues in my experience.
This code is more stylish and will run much faster (apparently)...
Code: [Select]
void lcd_outstr(const char *buffer, int buflen) {
   const char *endbuf;
   for(endbuf=buffer+buflen;buffer<endbuf&&*buffer;lcd_char(*buffer),++buffer);
}

I can see it could run faster.  But I have a habit of avoiding pointer arithmetic unless absolutely necessary.  I hate codes that fail when compiled with different flags.  If memory serves, I think Microsoft C had small, large, and huge memory model.  The char * changes to char FAR * or char HUGE *.  Use the wrong slash parameter and the code goes south because what you assume would fit into an int doesn't fit anymore.  So, I do pointer arithmetic only when there is a meaningful advantage.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #88 on: May 11, 2013, 04:30:58 am »
I've actually seen it used in a very unreadable way in code that was called "good" with a straight face. Of course, I'm still trying to figure out whether the circus of coding behind the GNU project is actually a very elaborate Monty Python skit that we programmers are being unknowingly compelled to participate in...
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #89 on: May 11, 2013, 04:37:34 am »
My God. In which way it is more stylish?
That's why I don't like C. The fight for putting as less code as possible.
Somehow it always takes my much more time to think what I want to write then typing itself. So I don't really care how small the source code is. I would rather prefer more easy reading.

Actually, it is not what is more stylish in the sense of what look better.  It is a personal style of work - like if you want your pencils to your left or to your right.

For me personally, I want to fit more code on the screen.  When more code is visible, it helps me grasp what is going on better.  Where I have a loop that does something simple, rather than having it being 4 or 5 lines of empty space with a few words in it.  I rather see it condensed into a single complex line.  My mind can move on to: ok, in this loop, there is this task to scan for tab after comma, and then next is blah blah blah.

With and empty { on one line, then buffer++ on another...  I can press down arrow 16 times and I am still reading the same conceptual idea whereas with a single complex line I can see many more conceptual task being done on a single screen.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #90 on: May 11, 2013, 05:04:19 am »
Assembler is looking more attractive with every post.   :o
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #91 on: May 11, 2013, 06:12:43 am »
Assembler is looking more attractive with every post.   :o

Ahem, don't let us scare you off.

Once you get a handle of it, you will/can develop your own style and ignore all those comments made.  The wide spread of opinion shows there are so many ways in C to accomplish the tasks and you will find the way best suits you.  We all settle into a mode that fits us best.  To say "this way works for me and should do it this way too" is like saying "can't see? wear my glasses, it works for me well and you too should do just fine with mine."

I am a little rusty with my C.  Arduino is not something I yet played with, so the code segments I show may not fit Arduino well.

If you are familiar with assembler already, C is easy.  I like assembler, but I rather debug C over debugging assembler any day.

Play with it.  Worst case is, you walk off a more knowledgeable man.

Rick
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: C function like printf but not sending to stdout? (XC8)
« Reply #92 on: May 11, 2013, 07:17:45 am »
Once you get a handle of it, you will/can develop your own style and ignore all those comments made.

A good way to make sure you aren't usable in a larger team. A diva with an own style is one of the worst things you can have in a larger team. Either people pull all in the same direction or you quickly end up with a heap of junk of a code base.

My experience with programmers venting their own coding spleen is they often use this, and defend this vigorously, to hide their incompetence. Especially in C there is a huge amount of an existing body of knowledge and conventions. Good, experienced, professional C programmers often don't even need a formal coding convention document. They can agree on one within minutes, or if there is some existing code they can pick up the project's existing conventions by just reading a few pieces of code.

By the way, your statements about pointer arithmetic are simply wrong.
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 6541
Re: C function like printf but not sending to stdout? (XC8)
« Reply #93 on: May 11, 2013, 12:45:42 pm »
This code is more stylish and will run much faster (apparently)...
Code: [Select]
void lcd_outstr(const char *buffer, int buflen) {
   const char *endbuf;
   for(endbuf=buffer+buflen;buffer<endbuf&&*buffer;lcd_char(*buffer),++buffer);
}
Even with compiler optimisation? That's not unheard of, and is the reason why Asm still has its place.

As an experienced C programmer I'd write this:
Code: [Select]
void lcd_outstr(const char *buffer, int buflen) {
 while(buflen-- && *buffer)
  lcd_char(*buffer++);
}
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1205
  • Country: 00
Re: C function like printf but not sending to stdout? (XC8)
« Reply #94 on: May 11, 2013, 01:02:10 pm »
I am always scared to use library functions.
They might cover much more than I need and cause a high memory usage.
I prepare most of my routines on myself. For example for LCD Integer display:

Code: [Select]
void LCD_Int(int16_t num)
{
    int16_t div;
    uint16_t i;
    if (num <0)
    {
        LCD_SendCHAR_4b('-');
        num = num * -1;
    }
    for (i=10000;i>=10;i=i/10)
    {
        if (num>=i)
        {
            div = num/i;
            num = num%i;
            LCD_SendCHAR_4b(div + '0');
        }
    }
    LCD_SendCHAR_4b(num + '0');
}

Same I have for doubles.
I am also planning to rewrite most of it in asm and maybe get rid of dividing.

I started programming with atmel 2051 with 2kb Flash and 128 RAM bytes. So still have in mind always optimize.
But maybe nowadays much cheaper is to just update the chip with higher memory version of 0,10$.

When you are doing both a division and a modulus of a particular number you should keep the C library function div() in mind.  Especially on lower-end MCUs.  The div() function will calculate both the quotient and remainder so it could save you some clock cycles. 

Of course you'll always want to check the compiler's output in both cases since compilers can be pretty clever.
 

Offline c4757p

  • Super Contributor
  • ***
  • Posts: 7805
  • Country: us
  • adieu
Re: C function like printf but not sending to stdout? (XC8)
« Reply #95 on: May 11, 2013, 01:16:49 pm »
Once you get a handle of it, you will/can develop your own style and ignore all those comments made.

A good way to make sure you aren't usable in a larger team. A diva with an own style is one of the worst things you can have in a larger team. Either people pull all in the same direction or you quickly end up with a heap of junk of a code base.

When you have an existing codebase, the style should always be conformity, and when you are starting one in a team, a style should always be chosen and agreed upon. For hobby stuff, though, it's definitely better to develop your own style and stick with it than to waste hours reading arguments and nerd rage about how every style out there is supposedly objectively wrong.
No longer active here - try the IRC channel if you just can't be without me :)
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #96 on: May 11, 2013, 06:12:04 pm »
Once you get a handle of it, you will/can develop your own style and ignore all those comments made.

A good way to make sure you aren't usable in a larger team. A diva with an own style is one of the worst things you can have in a larger team. Either people pull all in the same direction or you quickly end up with a heap of junk of a code base.

When you have an existing codebase, the style should always be conformity, and when you are starting one in a team, a style should always be chosen and agreed upon. For hobby stuff, though, it's definitely better to develop your own style and stick with it than to waste hours reading arguments and nerd rage about how every style out there is supposedly objectively wrong.

Can't disagree with that.  But David_AVD clearly is not developing profession code in a team.  So he needs to develop style best fit him.
 

Offline Rick Law

  • Super Contributor
  • ***
  • Posts: 2712
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #97 on: May 11, 2013, 06:29:50 pm »
A good way to make sure you aren't usable in a larger team...
...
By the way, your statements about pointer arithmetic are simply wrong.


Board@Work, David_AVD is NOT working in a team.  He is just exploring for his own.
I don't think you are relating to someone who merely is doing it for recreation...


Re: I am incorrect about pointer arithmetic
You are right for the world today but I was not referring to the world today.  What I said was I developed that habit when it was difficult to port pointer arithmetic.

I was working with compilers that ran on a 50k floppy.  I was porting to a different compilers that ran on 360k floppy.  That was a different world then.  Back then, floppies doesn't even interchange.  You have "soft sector floppies" and "hard sector floppies".  Hell, the compiler even has to load to specific memory addresses.  It was a different world then.
« Last Edit: May 11, 2013, 06:45:29 pm by Rick Law »
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #98 on: September 30, 2013, 06:27:55 am »
Sorry for reviving my old thread, but thought it better than create a new one as this is related.

I can't seem to work out the code to format a string given more than one variable.

I have minutes and seconds in two uint8_t variables that I want to present as a string in the "mm:ss" format, with zeroes instead of spaces for padding. (eg 00:05 for 5 seconds)

After looking at many C functions, I can't see how to give any of them more than one argument.  A nudge in the right direction would be appreciated.  Thanks.
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #99 on: September 30, 2013, 06:34:31 am »
You would want printf (print directly to stdout) or sprintf (write formatted text to a string in memory).

For example, to print your time string you might use something like:

Code: [Select]
printf("%2.2u:%2.2u", (unsigned int)minutes, (insigned int)seconds);
Here % introduces a format specifier, 2.2 specifies a field width of 2 with a precision of 2 (i.e. 2 digits printed), and u specifies an unsigned decimal integer.
« Last Edit: September 30, 2013, 06:40:37 am by IanB »
I'm not an EE--what am I doing here?
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #100 on: September 30, 2013, 06:52:44 am »
The warning I get with that is: "incompatible implicit declaration of built-in function 'sprintf' [enabled by default]".

I should mention this is with AVR GCC, not XC8.  In hindsight I should have started a new thread.

The code is:
Code: [Select]
sprintf(Buttons[BtnExtTime].Caption,"%u2.2:%u2.2",(unsigned int)mins,(unsigned int)secs);
 

Offline amyk

  • Super Contributor
  • ***
  • Posts: 6541
Re: C function like printf but not sending to stdout? (XC8)
« Reply #101 on: September 30, 2013, 07:29:00 am »
What is the type of Buttons[BtnExtTime].Caption ? sprintf is declared as taking something like (char*, char *, ...)

It's a variadic function - that means it can take a variable number of parameters, and in this case the 2nd one - the format string - gives meaning on how to interpret the parameters after it.

Also your format string should be %2.2u and not %u2.2 - the letter ends the conversion specifier so you're going to get e.g. "122.2:52.2" instead of "12: 2".
 

Offline IanB

  • Super Contributor
  • ***
  • Posts: 9593
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #102 on: September 30, 2013, 07:35:07 am »
instead of "12: 2"

Just FYI, a format specifier of %2.2u should print 2 as "02" with a leading zero. With that format you get a field width of 2 with 2 digits printed.
I'm not an EE--what am I doing here?
 

Offline Galaxyrise

  • Frequent Contributor
  • **
  • Posts: 526
  • Country: us
Re: C function like printf but not sending to stdout? (XC8)
« Reply #103 on: September 30, 2013, 08:20:14 am »
%02u will also give you at least two digits, 0-prefixed if needed.  I like doing it that way since that's also how you 0-prefix floats.

printf-style formatting does take some getting used to, but it's quite powerful and as such has been implemented in quite a few languages now. 

"incompatible implicit declaration of built-in function 'sprintf' [enabled by default]".
The compiler encountered a call to sprintf without being told what sprintf would look like.  That's normally ok because implicit declarations are enabled, but the compiler has knowledge of sprintf built in and that built-in prototype isn't compatible with the arguments you're passing it. So the compiler hopes you know what you're doing.  I would guess that warning means the built-in behavior won't run, and instead a call to a real function "sprintf" will be generated.

I'm not sure what the implicit declaration of sprintf looks like, but it doesn't have to be implicit.  To get the explicit declaration of sprintf, #include <string.h> Once the compiler has an explicit declaration, the warning will likely turn into an error (something like "could not convert parameter 2 from char const * to char *")
« Last Edit: September 30, 2013, 08:22:49 am by Galaxyrise »
I am but an egg
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: C function like printf but not sending to stdout? (XC8)
« Reply #104 on: September 30, 2013, 10:27:48 am »
Quote
The warning I get with that is: "incompatible implicit declaration of built-in function 'sprintf' [enabled by default]".

Include the header file where sprintf() is prototyped.
================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #105 on: October 01, 2013, 12:50:32 am »
Thanks again guys.  Those forgotten include files will be the death of me.   |O

The following is what I ended up with and it works well.

Code: [Select]
unsigned int mins, secs;
mins = ExtendedTime / 60;
secs = ExtendedTime % 60;
sprintf(Buttons[BtnExtTime].Caption,"%2.2d:%2.2d",mins,secs);
 

Offline ve7xen

  • Frequent Contributor
  • **
  • Posts: 671
  • Country: ca
    • VE7XEN Blog
Re: C function like printf but not sending to stdout? (XC8)
« Reply #106 on: October 02, 2013, 05:30:43 am »
This particular string will always be 5 characters long, so you could just generate it with assignment:
Code: [Select]
Buttons[BtnExtTime].Caption[0] = '0' + (ExtendedTime / 60) / 10;
Buttons[BtnExtTime].Caption[1] = '0' + (ExtendedTime / 60) % 10;
Buttons[BtnExtTime].Caption[2] = ':';
Buttons[BtnExtTime].Caption[3] = '0' + (ExtendedTime % 60) / 10;
Buttons[BtnExtTime].Caption[4] = '0' + (ExtendedTime % 60) % 10;
Buttons[BtnExtTime].Caption[5] = '\0'; // if necessary
73 de VE7XEN
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: C function like printf but not sending to stdout? (XC8)
« Reply #107 on: October 02, 2013, 06:47:11 am »
This particular string will always be 5 characters long, so you could just generate it with assignment:

That's pretty much exactly how I did it before asking.  I did want to learn how to do it the sprintf way for other uses though.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: C function like printf but not sending to stdout? (XC8)
« Reply #108 on: October 02, 2013, 10:11:48 am »
Generally, printf is costly in speed and execution and should be avoided, unless you are already using it.

My preference is to use itoa() or ltoa() or their variants - they are implemented on most compilers and even if they aren't, they are simple to write your own.

Be careful however that some implementations of itoa() / ltoa() are done through sprintf().
================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf