Hello, the following code
import strutils
proc sprintf(buf, frmt: cstring) {.header: "<stdio.h>",
importc: "sprintf",
varargs, noSideEffect.}
let
n = 1
format = "%2.2d"
var buf = ""
buf.sprintf(format, 1)
echo buf
echo "buf='" & buf & "'"
echo "buf='$1'" % buf
produces
01
buf=''
buf=''
why buf produces an output only in first case?
In this case the buffer actually is large enough as Nim (currently) makes the string at least 7 chars big. Instead echo just uses printf, which ignores the length of the Nim string and just prints until the \0 is encountered. Meanwhile & is written in Nim and respects the length field, which is still 0.
This should work:
import strutils
proc sprintf(buf, frmt: cstring) {.header: "<stdio.h>",
importc: "sprintf",
varargs, noSideEffect.}
let
n = 1
format = "%2.2d"
var buf = newString(8)
buf.sprintf(format, 1)
buf.setLen(buf.cstring.len)
echo "buf='" & buf & "'"
echo "buf='$1'" % buf
Which you can of course abstract away in a proc, but sprintf is often unsafe as you don't get to specify the size of buf. snprintf fixes this.I'm trying to rewrite it with snprintf:
import strutils
proc snprintf(buf, size: int, frmt: cstring) {.header: "<stdio.h>",
importc: "snprintf",
varargs, noSideEffect.}
let
n = 1
fmt = "%2.2d"
maxFmtLen = 5
var buf = newString(maxFmtLen)
buf.snprintf(maxFmtLen, fmt.cstring, n)
buf.setLen(buf.cstring.len)
echo buf
echo "buf='" & buf & "'"
echo buf
echo "buf='$1'" % buf
echo buf
but I get the error:
bug.nim(12, 4) Error: type mismatch: got (string, int, cstring, int)
but expected one of:
bug_fixed_snprintf.snprintf(buf: int, size: int, frmt: cstring)
what is wrong?