Author Topic: I hate C printf format specifiers. Alternatives?  (Read 20721 times)

0 Members and 1 Guest are viewing this topic.

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
I hate C printf format specifiers. Alternatives?
« on: August 27, 2015, 12:02:25 am »
I just can't seem to remember what all these almost randomly chosen letters do.  And after using a reference chart for the third time today, I wondered, am I alone?  Or are there others like me?  Maybe even someone who has designed an alternative, with user-friendliness in mind?

I know it would be non-standard, but I could still use it for some things.  Googling turned up some possibilities for C++, Haskell, and so on.  But not plain C.
 

Offline Macbeth

  • Super Contributor
  • ***
  • Posts: 2571
  • Country: gb
Re: I hate C printf format specifiers. Alternatives?
« Reply #1 on: August 27, 2015, 12:24:26 am »
Seriously? Nothing could be simpler. More modern stuff uses regular expressions. Try that then go back to the simplicity of printf()
 

Offline TopLoser

  • Supporter
  • ****
  • Posts: 1922
  • Country: fr
Re: I hate C printf format specifiers. Alternatives?
« Reply #2 on: August 27, 2015, 12:38:28 am »
Nothing could be more simple! Give us an example of how you would do it better?!
 

Offline rs20

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
Re: I hate C printf format specifiers. Alternatives?
« Reply #3 on: August 27, 2015, 12:43:52 am »
Conciseness = user friendliness when it comes to coding. You could write one where you go

printFbyChris("I have %DECIMAL(figures=5,show_leading_zeros=true) bananas", ...)

But I think even you would soon go back to

printf("I have %05d bananas", ...)
 

Offline TopLoser

  • Supporter
  • ****
  • Posts: 1922
  • Country: fr
Re: I hate C printf format specifiers. Alternatives?
« Reply #4 on: August 27, 2015, 12:49:23 am »
digits=5 surely?

and so the confusion builds!
 

Offline Zeyneb

  • Regular Contributor
  • *
  • Posts: 233
  • Country: nl
Re: I hate C printf format specifiers. Alternatives?
« Reply #5 on: August 27, 2015, 02:00:50 am »
I do like the old fashioned printf type specifiers. In engineering education I first learned C and later C++. Then I was suggested to use cout for text output. With all that type safety propaganda. I wasn't able to see the benefit of that and simply sticked to printf and it's comrades in stdio.h. For me it was easy to verify the correctness of something that fits into a single line.

I even do goto sometimes in C. No I don’t write spaghetti code. It is easier to follow a few goto’s than a complex while condition for me.
goto considered awesome!
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: I hate C printf format specifiers. Alternatives?
« Reply #6 on: August 27, 2015, 02:27:26 am »
I've used C for over 30 years now, I am quite used to the % format specifiers and I know the common ones like the back my hand, the more esoteric format specifiers I still have to look up.  But once you know them they are quick and concise to write.

However, I am still fond of the COBOL PICTURE clauses, even though I didn't have a COBOL career  :)

For those of us who remember Mark Williams COHERENT, there is a picture() function there, for C.  In 2015, they open-sourced COHERENT and that particular picture() call is available in the libmisc source.

picture(3101.1, "*$ZZZ,ZZZ.99", output_string) yields "$***3,101.10" in output_string.
picture(5.1, "ZZ99", output_string) yields "  05" in output_string. (two spaces and 2 digits)

http://www.nesssoftware.com/home/mwc/manpage.php?page=libmisc (scroll down to Pictures)

The main page is here http://www.nesssoftware.com/home/mwc/
COHERENT source is here : http://www.nesssoftware.com/home/mwc/source.php
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
  • There's more value if you figure it out yourself!
Re: I hate C printf format specifiers. Alternatives?
« Reply #7 on: August 27, 2015, 03:04:17 am »
I like sprintf() for flexibility and the ability to arbitrarily concatenate formatted strings (without using strcat())
If Chris is using Arduino - problem solved for simplicity, but not flexibility / performance.

OMG - I almost forgot the COBOL picture statement... clumsy, but certainly readable)
« Last Edit: August 27, 2015, 03:07:01 am by SL4P »
Don't ask a question if you aren't willing to listen to the answer.
 

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #8 on: August 27, 2015, 03:15:35 am »
Heh.  Maybe it is just me.

C is NOT my primary language.  So I see "d", and the first two thoughts that come to my mind is "double precision float".  Or "decimal", which in the contexts I'm more used to, doesn't mean base 10 - it means a number stored much like a string, with no limit on the number of digits or precision.  I know I can use "i" instead, and that makes more sense to me as an integer.  But it seems like everyone else uses "d", so I feel obliged to use it as well.  And then I don't mess with printf for a while, go back to old code and see "d", and get confused all over again.  I try to figure it out without the reference chart, and it goes something like this:

Hmm, "d" is an integer, right?  But wait, "u" is an unsigned integer, so that would make a signed integer "i', and that makes "d"...double?  Arg, gotta check that chart again...

Seriously, WHY did they assign two letters to the same darn thing?  I don't care what anyone says, this is NOT intuitive.

I'm also trying to code for portability to other hardware.  Currently in the middle of the second port, this time from 16 to 32 bit architecture.  Had the foresight to write it from the start using types like int16_t where appropriate, which I typedef'ed to I16 for conciseness.  So most of it's been super easy.  But I'm now getting some stack issues using printf.  In the process of looking into it, I find something that says in this scenario, I really should have been writing:

printf("I have %05" PRIi16 " bananas", ...)

Which is no longer concise, like [rs20]'s original example.  But at least it's totally unambiguous.  And different enough that I no longer feel obliged to use "d", when I really want to use "i".  Yet, if I want those bananas in hex, I have to do this:

printf("I have %05" PRIx16 " bananas", ...)

But what I'll end up doing is this:

printf("I have %05" PRIi16x " bananas", ...)

Remember I typedef'ed int16_t to I16?  That means I'm going to instinctively want to put that "i" in there, right before the "16", every time.  Which makes perfect sense, really, because IT IS STILL AN I16.  That I'm asking for output in hex, has NOTHING to do with the input data type, and should NOT replace or require changes to that convention.

So I can fix this with more defines.  Give myself "PRIi16x", or more likely "priI16X" which fits in better with my existing I16 convention, and whatever else I want to do that is comfortable and intuitive.  In fact, by adding a preprocessing wrapper around printf, I could make it accept any of these:

printf("I have %05" priI16 priX " bananas", ...) // I16, uppercase hex
printf("I have %05" priX priI16 " bananas", ...) // I16, uppercase hex
printf("I have %05" priI16 prix " bananas", ...) // I16, lowercase hex
printf("I have %05" prix priI16 " bananas", ...) // I16, lowercase hex


Which is slightly less concise, but even more intuitive.  Because then I don't even have to remember where in a naming convention the "x" is supposed to go.  I will not be confused on whether the "x" replaces "I" or not, even if I have recently seen someone else using "PRIx16".

And should I ever actually need a hex floating-point number (though I can't imagine why), I don't have to remember that somehow becomes "A".  What is that "A" supposed to stand for anyway?  Arcane?  Who thought that was even useful?  A signed hex integer is less weird, yet apparently impossible...  Seriously, the more I look at all this, the more arbitrary it seems.

Ok, rant mode off.

My intent in posting this question was that before doing my own defines and whatnot, I just wanted to see if anyone else had come up with something similar, but possibly more elegant.
« Last Edit: August 27, 2015, 03:27:25 am by Chris C »
 

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #9 on: August 27, 2015, 03:17:57 am »
For those of us who remember Mark Williams COHERENT, there is a picture() function there, for C.  In 2015, they open-sourced COHERENT and that particular picture() call is available in the libmisc source.

That looks similar to formatting functions I've used in other languages.  I'll have to check that out, thanks.

COBOL.  My grandma coded in that, no kidding. ;)
« Last Edit: August 27, 2015, 03:28:15 am by Chris C »
 

Offline obiwanjacobi

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: I hate C printf format specifiers. Alternatives?
« Reply #10 on: August 27, 2015, 06:43:23 am »
Seriously? Nothing could be simpler. More modern stuff uses regular expressions. Try that then go back to the simplicity of printf()

Uhh, regular expression are used for string parsing - not string formatting...


I share Chris' sentiments. My day job makes me program in C# that uses a different set of placeholders. Result is the same, I also have to look these up when it gets more complex. So I guess, no matter what you think up - when you cannot remember the logic behind the placeholders it will always feel as a PitA.
Arduino Template Library | Zalt Z80 Computer
Wrong code should not compile!
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3640
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #11 on: August 27, 2015, 06:54:28 am »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.
 

Offline jwm_

  • Frequent Contributor
  • **
  • Posts: 319
  • Country: us
    • Not A Number
Re: I hate C printf format specifiers. Alternatives?
« Reply #12 on: August 27, 2015, 07:04:38 am »

Hmm, "d" is an integer, right?  But wait, "u" is an unsigned integer, so that would make a signed integer "i', and that makes "d"...double?  Arg, gotta check that chart again...

Seriously, WHY did they assign two letters to the same darn thing?  I don't care what anyone says, this is NOT intuitive.

I know this one :), when reading text, %d is always base 10, while %i accepts any of the C standard number formats (like 0xff for 256, or 0177 for octal). This difference isn't important for printf because the default for %i is base 10, so it looks the same as %d, however for scanf there is a big difference. It would be weird for a specifier to work in scanf but not printf so printf accepts both even though they behave the same so you can reuse the same formatting strings to read/write the same data.

And there is nothing wrong at all with using %i in printf for int. I use it exclusively, most modern programmers do I think for the reasons you state.
« Last Edit: August 27, 2015, 07:07:59 am by jwm_ »
 

Offline android

  • Regular Contributor
  • *
  • Posts: 134
  • Country: au
Re: I hate C printf format specifiers. Alternatives?
« Reply #13 on: August 27, 2015, 08:08:16 am »
picture(3101.1, "*$ZZZ,ZZZ.99", output_string) yields "$***3,101.10" in output_string.
...and, on IBM mainframes at least, the conversion is done with a single machine instruction.  8)
Lecturer: "There is no language in which a double positive implies a negative."
Student:  "Yeah...right."
 

Offline tszaboo

  • Super Contributor
  • ***
  • Posts: 7374
  • Country: nl
  • Current job: ATEX product design
Re: I hate C printf format specifiers. Alternatives?
« Reply #14 on: August 27, 2015, 09:35:04 am »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.
You sit in front of a computer when writing C code. It takes 4 seconds to type c lib printf into google, but you can print a C reference guide (good ones are 2-4 pages) and stick it on the wall if you are a programmer.
I think it is the most convenient way of outputting a string. I find myself using it even if I'm programming in C++ or on Arduino for example. sprintf it to a buffer, serial.print the buffer, leave me alone with the made up bullshit. C string formatting is simple, elegant and it works regardless the architecture number of bits or platform.
 

Offline rs20

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
Re: I hate C printf format specifiers. Alternatives?
« Reply #15 on: August 27, 2015, 09:43:49 am »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.
You sit in front of a computer when writing C code. It takes 4 seconds to type c lib printf into google, but you can print a C reference guide (good ones are 2-4 pages) and stick it on the wall if you are a programmer.
I think it is the most convenient way of outputting a string. I find myself using it even if I'm programming in C++ or on Arduino for example. sprintf it to a buffer, serial.print the buffer, leave me alone with the made up bullshit. C string formatting is simple, elegant and it works regardless the architecture number of bits or platform.
This doesn't seem to refute the claim that printf is completely untyped. Also, the OP has outlined the not-so elegant hacks you need for your printf to work "regardless the architecture number of bits or platform".
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3640
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #16 on: August 27, 2015, 09:48:49 am »
Quote
Remember I typedef'ed int16_t to I16?  That means I'm going to instinctively want to put that "i" in there, right before the "16", every time.  Which makes perfect sense, really, because IT IS STILL AN I16.  That I'm asking for output in hex, has NOTHING to do with the input data type, and should NOT replace or require changes to that convention.
The problem with this specific strategy is that printf() commands are not type specifiers, they are format conversions. And if you understand the way that C passes arguments, you should know that "I16" is not the type of any actual argument to printf(). All arguments to a variadic function undergo the usual type conversions, which means that what printf() receives is simply an "int". It's seductive to think that you can fix C's unspecified-integer-width problems with type definitions and make everything a known number of bits, but this is not generally the case.

Quote
It takes 4 seconds to type c lib printf into google
More programmers who are only as smart as google  :palm:

Quote
sprintf it to a buffer, serial.print the buffer, leave me alone with the made up bullshit.
Excellent, I'll make sure to give your products special attention when it comes to stack overflow exploits.

Quote
it works regardless the architecture number of bits or platform.
Yes, as long as you don't care whether overflow is detected or how many bits are actually given.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: I hate C printf format specifiers. Alternatives?
« Reply #17 on: August 27, 2015, 10:41:01 am »
This document explains the interface of the printf family.
http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html
Notice that this is not a description of an implementation, but more the standard used. So results may vary depending on the laziness of the lib people.

There is a lot of implicit type conversion going on, you should be able to make it more strict using the length modifiers. Still, no errors will be shown, it's C, not java.
If you really don't like it, you can get angry for a week and create your own, it not impossible. But remember that the parameters occupy memory. So using %d if more efficient than using %int_16.t
http://chibios.sourceforge.net/html/group__chprintf.html
« Last Edit: August 27, 2015, 10:43:59 am by Jeroen3 »
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #18 on: August 27, 2015, 12:39:16 pm »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.

Since compilers do verify the printf arguments if you use a literal format and complain if you don't. IIRC GCC has a pragma that allows to write functions of your own with printf like format and have the compiler verify it.

EDIT:  from GCC manual:
format (archetype, string-index, first-to-check)
The format attribute specifies that a function takes printf, scanf, strftime or strfmon style arguments which should be type-checked against a format string. For example, the declaration:
          extern int
          my_printf (void *my_object, const char *my_format, ...)
                __attribute__ ((format (printf, 2, 3)));
« Last Edit: August 27, 2015, 01:07:08 pm by zapta »
 

Offline ralphd

  • Frequent Contributor
  • **
  • Posts: 445
  • Country: ca
    • Nerd Ralph
Re: I hate C printf format specifiers. Alternatives?
« Reply #19 on: August 27, 2015, 12:40:57 pm »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.
Smart compilers can recognize the printf call and check the parameters.
Unthinking respect for authority is the greatest enemy of truth. Einstein
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #20 on: August 27, 2015, 02:02:41 pm »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.

exactly, for that reason I prefer to create my collection of functions, one functions for every data type

uint32_t ---> put_uint32
sint32_t ---> put_sint32
char_t ---> put_char (which can be 8 or 16bit)
string_t ---> put_string

the code is also smaller than printf, and I do not need all the support for the stack

ADA works this way, and so my embedded C
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: I hate C printf format specifiers. Alternatives?
« Reply #21 on: August 27, 2015, 02:48:32 pm »
Translations become more complicated though.
With printf you can just swap the first arguments, with custom stuff and operator<< this becomes more work.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: I hate C printf format specifiers. Alternatives?
« Reply #22 on: August 27, 2015, 02:59:33 pm »
I agree. The elegance of printf is that you can mix fixed text and numbers. But nobody says you can't create your own printf. It isn't difficult to do that; there are many examples on how to create a function with a variable number of arguments. However.. some compilers (GCC for example) check the format specifier of printf against the type of the variable and emit a warning if there is a mismatch.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #23 on: August 27, 2015, 03:36:29 pm »
some compilers (GCC for example) check the format specifier of printf against the type of the variable and emit a warning if there is a mismatch.

SierraC does not, that was the first reason why I have decided to created a dedicated function, one function for every data_type.
ADA works exactly this way, so from my point of view I am simplifying my job (translating from ADA to C)
 

Offline free_electron

  • Super Contributor
  • ***
  • Posts: 8517
  • Country: us
    • SiliconValleyGarage
Re: I hate C printf format specifiers. Alternatives?
« Reply #24 on: August 27, 2015, 04:02:56 pm »
printf is unsafe ...
Professional Electron Wrangler.
Any comments, or points of view expressed, are my own and not endorsed , induced or compensated by my employer(s).
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3238
  • Country: gb
Re: I hate C printf format specifiers. Alternatives?
« Reply #25 on: August 27, 2015, 04:57:58 pm »
printf is unsafe ...

printtf is not type-safe, which is a very different thing to being fundamentally unsafe.  It means the programmer must ensure he or she is using the function correctly rather than relying on run time error detection to save them from their incompetence.
 

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #26 on: August 27, 2015, 05:07:28 pm »
The problem with this specific strategy is that printf() commands are not type specifiers, they are format conversions. And if you understand the way that C passes arguments, you should know that "I16" is not the type of any actual argument to printf(). All arguments to a variadic function undergo the usual type conversions, which means that what printf() receives is simply an "int".

That's not exactly true.  Say you have a two variables, both strongly typed.  One int16_t, one int32_t.

Print those variables on a 32-bit system.  You can use "%d" for both.  You're correct that the int16_t is converted to an int (int32_t) upon being passed to the varadic function.

But on a 16-bit system, you have to use "%d" for the int16_t, and "%ld" for the int32_t.

What would you call the printf() command "l" in that case, if not a type specifier?
« Last Edit: August 27, 2015, 05:28:14 pm by Chris C »
 

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #27 on: August 27, 2015, 05:18:57 pm »
Well I have created it, but … I do not find it so good

No need to make that from scratch.  I have a "tiny printf" in my reference library, from Kustaa Nyholm, that looks like it would make an excellent starting point:

http://www.sparetimelabs.com/tinyprintf/index.html

Note that it could be made even tinier, especially if you're going to add support for more options.  There's a "switch" statement there based on char values, and because those values are sparse (non-contiguous), it compiles to a series of individual "if" tests, rather than a jump table.

You can instead put the chars in an array.  Add a little code to try to look up the current char in the array.  If found, use the array index to drive the switch statement.  The cases will be contiguous, and will compile to a jump table.
 

Offline ralphd

  • Frequent Contributor
  • **
  • Posts: 445
  • Country: ca
    • Nerd Ralph
Re: I hate C printf format specifiers. Alternatives?
« Reply #28 on: August 27, 2015, 11:41:04 pm »
Well I have created it, but … I do not find it so good

No need to make that from scratch.  I have a "tiny printf" in my reference library, from Kustaa Nyholm, that looks like it would make an excellent starting point:

http://www.sparetimelabs.com/tinyprintf/index.html

Note that it could be made even tinier, especially if you're going to add support for more options.  There's a "switch" statement there based on char values, and because those values are sparse (non-contiguous), it compiles to a series of individual "if" tests, rather than a jump table.

You can instead put the chars in an array.  Add a little code to try to look up the current char in the array.  If found, use the array index to drive the switch statement.  The cases will be contiguous, and will compile to a jump table.

There's also Elm Chan's xprintf.
http://elm-chan.org/fsw/strf/xprintf.html
Unthinking respect for authority is the greatest enemy of truth. Einstein
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: I hate C printf format specifiers. Alternatives?
« Reply #29 on: August 27, 2015, 11:53:46 pm »
There's also Elm Chan's xprintf.
http://elm-chan.org/fsw/strf/xprintf.html
His reason for creating it is because the regular printf is sometimes too large. However creating functions with different names sucks because it makes code non-portable. If you use or create your own small/micro printf better call it printf. Since most C libraries export printf as weak the 'local' printf will take precedence over the library provided printf. Problem solved.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: I hate C printf format specifiers. Alternatives?
« Reply #30 on: August 28, 2015, 05:02:55 am »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.

exactly, for that reason I prefer to create my collection of functions, one functions for every data type

uint32_t ---> put_uint32
sint32_t ---> put_sint32
char_t ---> put_char (which can be 8 or 16bit)
string_t ---> put_string

the code is also smaller than printf, and I do not need all the support for the stack

ADA works this way, and so my embedded C

And it is very easy to provide also formatted versions of the put_XXX functions. The parameters might be the field width and the bitset of the flags (FMT_LEFT, FMT_RIGHT, FMT_ZEROPAD, FMT_LOCASE, FMT_UPCASE, etc.) passed either as two uint8s or one uint16 containing the width and the flags.
 

Offline rs20

  • Super Contributor
  • ***
  • Posts: 2318
  • Country: au
Re: I hate C printf format specifiers. Alternatives?
« Reply #31 on: August 28, 2015, 05:44:43 am »
The big problem with C interfaces like printf() isn't that they are hard to remember, it's that they are completely untyped.

exactly, for that reason I prefer to create my collection of functions, one functions for every data type

uint32_t ---> put_uint32
sint32_t ---> put_sint32
char_t ---> put_char (which can be 8 or 16bit)
string_t ---> put_string

the code is also smaller than printf, and I do not need all the support for the stack

ADA works this way, and so my embedded C

This is my approach as well, but I didn't want to suggest such a manual approach. I find writing these five-line functions relaxing, but I was worried it was just me!

The other great bonus with this approach is that if you use "fixed point integers"* (which are much faster than floats on integer-only hardware), you can write yourself a function that inserts a decimal point wherever you want. So it's just a little extra "decimal_points" argument which drops a decimal point at the right point in the string (which is being directly written to the UART of course, no actual string buffers here), and you get human-readable floating point numbers without a single byte of FPU-emulating code or printf.

* i.e., an integer that you just have a comment next to saying "this is actually in millionths

Here's a reference example (completely untested, just dumped into the forum). A little bit recursion-heavy I grant you.

Code: [Select]
void printString(const char* s) {
  while (*s) printChar(*s++);
}

void printInt32(int32_t v, int8_t decimals) {
  if (v < 0) {
    printChar('-');
    printInt32(-v); // Bug for the reader to fix: will infinite loop if -2^31 is input.
    return;
  }
  int32_t div10 = v / 10;
  if (div10) {
    printInt32(div10, decimals - 1);
    if (decimals == 1) printChar('.');
  }
  printChar(v % 10 + '0');
}

void loop() {
  int32_t reading = read_from_ds18b20(...); // Read temperature from DS18B20+. LSB is 2^-4, i.e. 0.0625
  int32_t fixed_point = reading * 625; // Convert to fixed point with 4 decimal places
  printString("Temperature: ");
  printInt32(fixed_point, 4);
  printString(" degrees C\n");

  // Temperature: -2.4375 degrees C
}
« Last Edit: August 28, 2015, 05:49:49 am by rs20 »
 

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #32 on: August 28, 2015, 08:57:13 pm »
Thank you everyone for the ideas!  I haven't decided which method I'm going to use yet, I have a few days before I need to.

Just to see what would result, I spec'ed out another method from scratch.  I'm curious how intuitive and readable others find it.  If anyone cares to indulge me on that...

The format specifier starts with '%' as usual, followed immediately by the fully spelled out variable type (or typedef).  Then optional other stuff, which you get no hints on.  Finally, it's terminated with a ';'.  See how fast you pick up on it from these examples:

Code: [Select]
"%I16;"
  123 = "123"
  -123 = "-123"

"%UI32 h;"
  0x000000FF = "ff"

"%UI32 H 8;"
  0x000000FF = "000000FF"

"%UI8 b 8;"
  3 = "00000011"

"%Float;"
  0 = "0"
  1 = "1"
  1.23 = "1.23"
  1.237 = "1.237"

"%Float .2;"
  0 = "0.00"
  1 = "1.00"
  1.23 = "1.23"
  1.237 = "1.24"

"%Float .0-2;"
  0 = "0"
  1 = "1"
  1.23 = "1.23"
  1.237 = "1.24"

"%Float 3.3;"
  1 = "001.000"
  37.1827 = "037.183"

"%Float <12;"
  -1.23 = "-1.23        "

"%Float , +s$ .2 >12;"
  -1234.56 = "  -$1,234.56"
   1234.56 = "   $1,234.56"

"%Float , +S$ .2 >12;"
  -1234.56 = "  -$1,234.56"
   1234.56 = "  +$1,234.56"

"%Float , +$S .2 >12;"
  -1234.56 = "  $-1,234.56"
   1234.56 = "  $+1,234.56"

"%Float .2 >12 +$S ,;"
  -1234.56 = "  $-1,234.56"
   1234.56 = "  $+1,234.56"
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #33 on: August 30, 2015, 04:22:10 pm »
Thank you everyone for the ideas!  I haven't decided which method I'm going to use yet, I have a few days before I need to.

Just to see what would result, I spec'ed out another method from scratch.  I'm curious how intuitive and readable others find it.  If anyone cares to indulge me on that...

The format specifier starts with '%' as usual, followed immediately by the fully spelled out variable type (or typedef).  Then optional other stuff, which you get no hints on.  Finally, it's terminated with a ';'.  See how fast you pick up on it from these examples:

Code: [Select]
"%I16;"
  123 = "123"
  -123 = "-123"

"%UI32 h;"
  0x000000FF = "ff"

"%UI32 H 8;"
  0x000000FF = "000000FF"

"%UI8 b 8;"
  3 = "00000011"

"%Float;"
  0 = "0"
  1 = "1"
  1.23 = "1.23"
  1.237 = "1.237"

"%Float .2;"
  0 = "0.00"
  1 = "1.00"
  1.23 = "1.23"
  1.237 = "1.24"

"%Float .0-2;"
  0 = "0"
  1 = "1"
  1.23 = "1.23"
  1.237 = "1.24"

"%Float 3.3;"
  1 = "001.000"
  37.1827 = "037.183"

"%Float <12;"
  -1.23 = "-1.23        "

"%Float , +s$ .2 >12;"
  -1234.56 = "  -$1,234.56"
   1234.56 = "   $1,234.56"

"%Float , +S$ .2 >12;"
  -1234.56 = "  -$1,234.56"
   1234.56 = "  +$1,234.56"

"%Float , +$S .2 >12;"
  -1234.56 = "  $-1,234.56"
   1234.56 = "  $+1,234.56"

"%Float .2 >12 +$S ,;"
  -1234.56 = "  $-1,234.56"
   1234.56 = "  $+1,234.56"

About the same complexity of the standard, if not more complex.

Resistance is futile, join the Borg.
 

Offline Chris CTopic starter

  • Frequent Contributor
  • **
  • Posts: 259
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #34 on: August 30, 2015, 11:40:24 pm »
About the same complexity of the standard, if not more complex.

Oh well.  Thank you for the honest answer!
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #35 on: August 31, 2015, 12:11:13 am »
Is there an online printf calculator similar to the online regex calculators?
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: I hate C printf format specifiers. Alternatives?
« Reply #36 on: August 31, 2015, 01:03:30 am »
Is there an online printf calculator similar to the online regex calculators?
I'm not sure whether that is useful. In my experience the interpretation of certain format specifiers depends on the implementation  :palm:
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #37 on: September 01, 2015, 10:20:01 pm »
printf and the Uncontrolled Format String  :palm: :palm: :palm:
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: I hate C printf format specifiers. Alternatives?
« Reply #38 on: September 01, 2015, 10:23:05 pm »
Using non-constant strings in printf won't compile in a decent C compiler. GCC cannot even be coerced into doing something stupid like that. All in all not really an issue.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #39 on: September 01, 2015, 10:23:11 pm »
a good solution in C++  :-//
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #40 on: September 01, 2015, 10:26:13 pm »
Using non-constant strings in printf won't compile in a decent C compiler

but … SierraC will  :palm: :palm: :palm:

(it's a cross compiler, DOS-x86 to m68k-baremetal
it was used by Texas Instruments for their 68K pocket calculators
TI89, TI92, etc ...)
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #41 on: September 02, 2015, 12:35:31 am »
I wrote some code for a Pascal compiler once, so that "Write" could generate formatted output.
Ordinary Pascal apparently believing that such a thing was unnecessary, of course.   I believe I used Fortran-style format strings.  (Hey, it was ~1979, and making the output compatible with fortran READ statements was one of the big goals.  You know, so that people could use Pascal for "Serious programming.")
Some of the ugliness in printf() formats comes from being based on fortran formats, I think...

Personally...  If you use printf() often enough, you'll learn the format codes.  The ones that you don't use often enough are OK to need to look up.

Quote
Uncontrolled Format String
I also once wrote a terminal emulator for the PC where I wanted to use the emulator itself for formatting help and menu screens and such, and I added "escape sequences" that would display internal program variables.  Like "<ESC> V <string address>";  That never quite made it to "productization", and I didn't notice what a horrible source of bugs it was until years (decades?) later...
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #42 on: September 02, 2015, 02:17:39 am »
It's also interesting that in C++11 you can use std::to_string:

Code: [Select]
std::string var = "sometext" + std::to_string(somevar) + "sometext" + std::to_string(somevar); 

A bit pedantic, but safe.
 

Offline obiwanjacobi

  • Frequent Contributor
  • **
  • Posts: 988
  • Country: nl
  • What's this yippee-yayoh pin you talk about!?
    • Marctronix Blog
Re: I hate C printf format specifiers. Alternatives?
« Reply #43 on: September 02, 2015, 07:54:28 am »
It's also interesting that in C++11 you can use std::to_string:

Code: [Select]
std::string var = "sometext" + std::to_string(somevar) + "sometext" + std::to_string(somevar); 

A bit pedantic, but safe.


But not so optimal concerning memory allocations?
Arduino Template Library | Zalt Z80 Computer
Wrong code should not compile!
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #44 on: September 02, 2015, 12:10:40 pm »
But not so optimal concerning memory allocations?

unfortunately, it's the price to pay
I can't see better solutions in terms of safer solutions :-//
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: I hate C printf format specifiers. Alternatives?
« Reply #45 on: September 02, 2015, 07:49:08 pm »
For one or two ad hoc conversions to strings, then ok, go ahead and use std::to_string().  But for long formatted output, then stringstreams are also typesafe, cleaner looking, and more C++ ' ish if that's even a word :)

If I saw someone writing C++ code using a series of chained std::to_string() like that I'd barf first, then take him outside for a talk :)

Note that GNU libc++ delegates to snprintf() for all calls to std::to_string().

There is also the  C++ Format Library. Apparently it's heavily optimized for speed.

Here's some examples from the documentation:
Code: [Select]
fmt::print("Hello, {}!", "world");  // uses Python-like format string syntax
std::string s = fmt::FormatInt(42).str();   // convert to std::string

// indexed and repeated arguments
std::string s = fmt::format("{0}{1}{0}", "abra", "cad");
// Result: s == "abracadabra"

std::string s = fmt::format("{:*^30}", "centered");  // use '*' as a fill char
// Result: s == "***********centered***********"

std::string s = fmt::format("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
// Result: s == "int: 42;  hex: 2a;  oct: 52; bin: 101010"
// with 0x or 0 or 0b as prefix:
std::string s = fmt::format("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}", 42);
// Result: s == "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"




A comparison of integer conversions using various formatting libraries is here:   http://zverovich.net/2013/09/07/integer-to-string-conversion-in-cplusplus.html
« Last Edit: September 02, 2015, 07:51:36 pm by codeboy2k »
 

Offline linux-works

  • Super Contributor
  • ***
  • Posts: 1997
  • Country: us
    • netstuff
Re: I hate C printf format specifiers. Alternatives?
« Reply #46 on: September 02, 2015, 08:15:02 pm »
Is there an online printf calculator similar to the online regex calculators?

its called python.

lol

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: I hate C printf format specifiers. Alternatives?
« Reply #47 on: September 02, 2015, 09:24:22 pm »
Using non-constant strings in printf won't compile in a decent C compiler. GCC cannot even be coerced into doing something stupid like that. All in all not really an issue.

As far as I can tell, GCC doesn't care, even with all warnings on...  What am I missing?

Code: [Select]
/tmp$ cat test.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    char format[20];
    sprintf(format,"%s","Format %s\r\n");
    printf(format,"Hello!");
    return 0;
}
/tmp$ gcc -Wall -o test test.c
/tmp$ ./test
Format Hello!
/tmp$
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: I hate C printf format specifiers. Alternatives?
« Reply #48 on: September 02, 2015, 10:37:34 pm »
Good question. Last time I tried with GCC there was no way around it. Perhaps your array gets optimised into a constant? Try using argv[1] as the format string.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Wim_L

  • Regular Contributor
  • *
  • Posts: 212
  • Country: be
Re: I hate C printf format specifiers. Alternatives?
« Reply #49 on: September 02, 2015, 10:57:58 pm »
There is no requirement that the string passed to printf or fprintf is a constant string literal.

The type of the format string is specified as follows in the C99 standard: "const char * restrict format".

The restrict can be disregarded here, it's a requirement that the format string won't be aliased with any other variable passed into the function. So, "const char * format". The const does NOT mean that this can only point to string constants! It can point to modifiable strings too. The const is simply a promise in the function declaration that the printf function will not modify the string through that pointer argument.

Passing a string variable into printf as a format string is fine. GCC may warn about this, depending on its compilation flags (-Wformat-security https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html), but it's no error. It can certainly be dangerous if you're passing unchecked user input into it, that's something you definitely shouldn't do.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: I hate C printf format specifiers. Alternatives?
« Reply #50 on: September 03, 2015, 05:34:56 am »
This is because the location of const can cause confusion for many programmers.
https://en.wikipedia.org/wiki/Const_(computer_programming)#Pointers_and_references

Printf doesn't care where the format string comes from. You can generate multiple tables, for each language, of format strings which you can select. And printf just delivers. You can even have the user enter one at runtime. It is unfortunate printf can not dereference pointers, if it could it would be another bit more helpful displaying templated layouts.
« Last Edit: September 03, 2015, 05:37:48 am by Jeroen3 »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: I hate C printf format specifiers. Alternatives?
« Reply #51 on: September 03, 2015, 05:49:21 am »
Quote
But not so optimal
I was thinking of mentioning that things like the "picture" based formatting have to be pretty expensive at runtime.  Something like ForTran can do a lot of the format processing at compile time because the feature is part of the language, but library-based functions as required by C are a lot harder to do.  The current printf() seems like it's a pretty reasonable compromise (although, I think printf() can be a lot "heavier" than some of the simple versions would lead you to believe.  I think I've seen printf implementations that end up calling malloc(), and running through the formatting twice for one reason or another.)
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #52 on: September 04, 2015, 10:03:28 am »
yet an other C++ alternative: C++format  :-+
 

Offline legacy

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: I hate C printf format specifiers. Alternatives?
« Reply #53 on: September 04, 2015, 10:05:50 am »
the new strategy uses the variadic template method.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26906
  • Country: nl
    • NCT Developments
Re: I hate C printf format specifiers. Alternatives?
« Reply #54 on: September 04, 2015, 02:12:43 pm »
There is no requirement that the string passed to printf or fprintf is a constant string literal.
True but as I wrote before some compilers enforce that a format specifier is a string literal and not a pointer to a variable to prevent format string attacks.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf