# ArgumentError: First argument to \`@sprintf\` must be a format string

**URL:** <https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697>\
**Category:** General Usage\
**Tags:** question, package, printf\
**Created:** [May 1, 2024, 2:52pm UTC](https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697 "2024-05-01T14:52:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [May 1, 2024, 2:52pm UTC](https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697/1 "2024-05-01T14:52:26Z")

</div>

```julia
julia> using Printf

julia> @sprintf("%.2f", 3.14159)
"3.14"

julia> @sprintf("%."*"3"*"f", 3.14159)
ERROR: ArgumentError: First argument to `@sprintf` must be a format string.

julia> format_str = "%.2f"
"%.2f"

julia> @sprintf(format_str, 3.14159)
ERROR: ArgumentError: First argument to `@sprintf` must be a format string.

```

Then how to write a function that returns a formatted string such as:

```julia
function fun(digits, num)
    return @sprintf("%." * string(digits) * "f", num)
end

```

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [May 1, 2024, 3:03pm UTC](https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697/2 "2024-05-01T15:03:37Z")

</div>

```julia
julia> using Printf

julia> function fun(digits::Integer, num::Real)
           fmtstr = "%." * string(digits) * "f"
           fmt = Printf.Format(fmtstr)
           return Printf.format(fmt, num)
       end
fun (generic function with 1 method)

julia> fun(3, π)
"3.142"

julia> fun(10, π)
"3.1415926536"

```

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [May 1, 2024, 3:10pm UTC](https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697/3 "2024-05-01T15:10:26Z")

</div>

Thanks!!! But, why can’t the format string be replaced by a `format_str`?

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [May 1, 2024, 3:20pm UTC](https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697/4 "2024-05-01T15:20:21Z")

</div>

`@sprintf` needs a string _literal_ (not just a variable whose value is a string, but an actual typed-in string), because the macro expands when Julia first reads the code, and generates the `Format` object then. This is efficient, since it only happens once (not every time your function is called). However, it is incompatible with the formatting being dynamic.

Using the function API instead of the macro API as @fatteneder showed allows you construct the `Format` object dynamically (but it will happen every time that code runs).

I think the error message here could be clearer, since “must be a format string” doesn’t quite point to the issue.

---

<div class="post-metadata">

**Author:** ![WuSiren](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wusiren/32/42529_2.png) [@WuSiren](https://discourse.julialang.org/u/WuSiren)\
**Post date:** [May 1, 2024, 3:26pm UTC](https://discourse.julialang.org/t/argumenterror-first-argument-to-sprintf-must-be-a-format-string/113697/5 "2024-05-01T15:26:30Z")

</div>

Oh, I see. Many thanks! 🤝 🤝
