Skip to content

please enhance Serial by a printf() method like ANSI C printf! #3586

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
shiftleftplusone opened this issue Jul 25, 2015 · 19 comments
Closed
Milestone

Comments

@shiftleftplusone
Copy link

please enhance Serial by a Serial.printf() method like ANSI C printf()!
The current output features are far too poor!

So output should be possible by a formatstring and a multi-format-multiple-argument list, including e.g.,

%d, %ld, %c, %f, %o, %s,  +  -  .number  .*  \n  \t  ...

just as shown here:
http://www.cplusplus.com/reference/cstdio/printf/

OT:
I'm really curious why this effing code block formatting does not work! What a poor editor!

@matthijskooijman
Copy link
Collaborator

@cmaglie, I'll leave this one for you...

I'm really curious why this effing code block formatting does not work! What a poor editor!

You should be using backticks (same key as the tilde ~), not normal quotes. I corrected them for you.

@shiftleftplusone
Copy link
Author

thanks a lot, then it's just about the first part (the printf thing) yet... ;)

@q2dg
Copy link

q2dg commented Jul 26, 2015

@shiftleftplusone
Copy link
Author

I don't see there if or how the issue has been fixed meanwhile, but Serial.printf() by multiple parameters and multiple formats is important to be provided (not just a single "%f" but all of the formatters by a multi-format string!)
Just like, e.g.

   Serial.printf ("Characters: %c %c \n", 'a', 65);
   Serial.printf ("Decimals: %d %ld\n", 1977, 650000L);
   Serial.printf ("Preceding with blanks: %10d \n", 1977);
   Serial.printf ("Preceding with zeros: %010d \n", 1977);
   Serial.printf ("Some different radices: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
   Serial.printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
   Serial.printf ("Width trick: %*d \n", 5, 10);
   Serial.printf ("%s \n", "A string");

it's currently extremely annoying that if one wants to write a line containing multiple strings and multiple numbers one has to write each single string and each single number individually by a mound of a billion single Serial.print()'s

@pwillard
Copy link

sprintf() is a nominal workaround

@shiftleftplusone
Copy link
Author

theoretically there are many workarounds conceivable, but my topic is about the issue, not about a workaround.
Moreover, sprintf() lacks of the "%f" formatter for AVRs, so actually this would not even be a workaround at all.
:-/

@PaulStoffregen
Copy link
Contributor

I implemented Serial.printf() on Teensy. If Arduino ever wants to implement this feature, it's only a small amount of open source code.

it's currently extremely annoying that if one wants to write a line containing multiple strings and multiple numbers one has to write each single string and each single number individually

I agree, it is annoying to write several lines, when you know how to do it with a single printf() line.

But Arduino's design decision is about other people reading the code, especially those not familiar with the complexities of printf format strings. For them, reading sketches with complex syntax is annoying. So is having to learn a cryptic syntax before being about to write similar lines.

I imagine you're unmoved by this thinking, but my point it not to convince you. My point is to explain why Arduino has resisted Serial.printf(). If you better understood Arduino's point of view, perhaps you could compose a more compelling argument? Obviously you don't yet understand their point of view, because the best argument you've been able to muster is that you, personally, as an experienced C programmer, are annoyed by having to write multiple simple lines. You're rather compose 1 complex line of code.

Can you at least try to imagine how that must sound to a group of designers who overriding goal is simplicity for a novice-oriented system that priorities ease-of-learning above all else?

@q2dg
Copy link

q2dg commented Jul 31, 2015

@PaulStoffregen What do you think about https://github.com/arduino/Arduino/issues/3546 (and #3551) ?

@PaulStoffregen
Copy link
Contributor

I have mixed feelings regarding both of those.

Likewise, I believe printf() is great for experts, but I also recognize the Arduino Team's concerns.

I do not have all the answers to these sorts of tough design trade-offs!

@shiftleftplusone
Copy link
Author

printf is not for experts, it's just for C programmers who are used to stdio.h, and it's just the same for sprintf() which is already implemented by Sketch (apart from this effing float formatting issue for AVRs).
The rest it's all the same:
for printf(),
for sprintf(),
for fprintf(),
for vsprintf(),
for Serial.printf()...

http://www.cplusplus.com/reference/cstdio/printf/

@PaulStoffregen
Copy link
Contributor

Ok then, I guess that's a "no", you can't try to understand Arduino's point of view?

@shiftleftplusone
Copy link
Author

not quite,
if one has a small AVR, one does not need to #include either lib, e.g., feat. full stdio.h printf() functionality and having more free RAM instead,
but who wants full stdio.h printf() functionality should be able to #include a lib in order to have this functionality

@shiftleftplusone
Copy link
Author

I think the point, why we often talk at cross purposes, is:
Arduino is coding in C,
and for C there are standards like ANSI C definitions and syntax rules plus additional standardized libs, e.g.
stdio.h (printf, sprintf, fprintf, gets, fgets, scanf,...)
plus other ones like math.h, stdlib.h,...
First of all, Arduino C should apply to the standards,
and if Arduino wants to create additional API functions to make it easier for beginners or even experts who lack of RAM, it's surely appreciated!
But 1st of all the (complete) standard features should be provided (as a basic option by #include-able standard libs).

@PaulStoffregen
Copy link
Contributor

For anyone else who wants Serial.printf(), please understand these 2 arguments do NOT work:

  1. Convenience for experienced C programmers: Arduino is a system designed for novices. Ease of learning for absolute beginners is the overriding design goal. Any API requests for advanced features must consider their immediate and long-term (as experts publish examples and libraries) impact on novices.

  2. Standards compliance: Arduino achieved success where many others failed, because of its design focus on simplicity, even when in conflict standards and well-established (but complex) programming practices. Attempting to argue standards compliance, at the expense of simplicity, is utter ignorance of the path that made Arduino so successful.

In closing this issue, I want to give some guidance to those who will inevitably being up Serial.printf() again and again. Please, do yourself a favor, try to express your argument from a viewpoint of understanding Arduino's design goals.

@shiftleftplusone
Copy link
Author

I am not experienced in C -
I started programming C 1 year ago, when I started programming with Arduinos!
But I have minor experience using Lego Mindstorms NXC over a couple of years.

I understand that Arduino implements beginner-friendly API functions, but that does not mean that Arduino has to exclude and drop and abandon all basic C facilities such as stdio.h functions in return.
Finally sprintf() is already there, but regrettably mutilated on AVRs.

The C concept is based on libraries which can be optionally #included or not in order to decide which funtionality is wanted and which one not.

  • Arduino should just apply to this principle.

@q2dg
Copy link

q2dg commented Jul 31, 2015

This is another approach: http://www.arduiniana.org/libraries/streaming

@shiftleftplusone
Copy link
Author

I don't see whether this has anything to do with my intention of my TOP!
My TOP is about a multi-format plus a multi-argument-list of parameters passed to a serial print function, comparable and syntax-compatible to printf() writing to stdout (strings, ints, floats, bytes, formatted by %d, %ld, %c, %f, %o, %s, + - .number .* \n \t ... all at once)
http://www.cplusplus.com/reference/cstdio/printf/

I hate it having to write each parameter one by one and being unable to format numbers adequately and suitably !
Serial. print() may stay as it is, suitable to beginners,
but Serial.printf() should provide standard (stdio.h) features additionally!

Serial.printf ("Characters: %c %c \n", 'a', 65);
Serial.printf ("Decimals: %d %ld\n", 1977, 650000L);
Serial.printf ("Preceding with blanks: %10d \n", 1977);
Serial.printf ("Preceding with zeros: %010d \n", 1977);
Serial.printf ("Some different radices: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
Serial.printf ("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
Serial.printf ("Width trick: %*d \n", 5, 10);

@ffissore ffissore modified the milestone: Release 1.6.6 Aug 3, 2015
@BrentWilkins
Copy link
Contributor

Does this help? http://playground.arduino.cc/Main/Printf

@shiftleftplusone
Copy link
Author

thank you, but the installation guide is very complicated, and moreover they say:
"Also note that by default the Arduino IDE does not set the AVR linker options to support floating point in the xxprintf() routines. So while that saves quite a bit of code space on the AVR builds, it means that printf() functions cannot be used for floating point output on the AVR. "
To have the %f or %E formatters is indispensable!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants