PrintEx icon indicating copy to clipboard operation
PrintEx copied to clipboard

sprintf() does not terminate job by ’\0’

Open jirkaptr opened this issue 7 years ago • 3 comments

Improving printf() and its derivatives is very welcome and useful. Unfortunately, I encountered issue in version 1.2.0: The sprintf() function does not terminate its job by writing '\0'. One practical consequence is that the resulting string could be printed as infinite. In the example basic_usage.ino this error is masked because the buff is filled in line #28 longer than in line #21.

In version 1.1.9 this error has not been detected.

BTW: Before experiments, it is necessary to fix the error in line #28 – i.e. missing specification %f.

jirkaptr avatar Feb 09 '18 14:02 jirkaptr

Can you provide an example? I am unable to reproduce this.

scottchiefbaker avatar Jan 31 '19 21:01 scottchiefbaker

A basic fix of the problem is done here: #https://github.com/jirkaptr/PrintEx/commit/ffbfa652c15243b1efad0d587df34d27061af344?diff=unified and later fixed here: #https://github.com/jirkaptr/PrintEx/commit/8644544617fe870cabb76805ba3dd9e77a88cc55

However, to achieve full compatibility with the standard, sprintf() should return the number of written characters. This feature is not reached by linked fix.

To obtain the number of written characters you can use strlen() or an emergent incompatible solution as follows: #define sprintf(buff, i, str, ...) {*(buff + (*i=GString(buff).printf(str, VA_ARGS)) ) = 0;} where i returns the number of stored characters. Note: specifiers %n, %p (and maybe %r - not tested) are not counted!

jirkaptr avatar Feb 02 '19 20:02 jirkaptr

I encountered this - the \0 does not get written into the destination although it returns the correct number of characters written. // Try with and without "#include <PrintEx>" /*

WITH PrintEx (bug is obvious): 36 0 36 36 Testing 1234 4321RSTUVWXYZ0123456789 36 WITHOUT PrintEx 36 0 36 36 Testing 1234 4321 14 Run with line below and with line below commented out to re-produce */

#include <PrintEx.h> const char buff1 [] = "ABCEDFGHIJKLMNOPQRSTUVWXYZ0123456789"; char buff3[100]={0};

void setup() { Serial.begin(115200); Serial.println(strlen(buff1)); Serial.println(strlen(buff3)); strcpy(buff3, buff1); Serial.println(strlen(buff1)); Serial.println(strlen(buff3)); int len = sprintf(buff3, "Testing %d %d", 1234, 4321); Serial.println(buff3); Serial.println(len); Serial.println(strlen(buff3));

} void loop() {}

TensorMan avatar May 19 '20 05:05 TensorMan