# Convert a NTuple{N,UInt8} to a String and back?

**URL:** <https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720>\
**Category:** General Usage\
**Tags:** question, strings\
**Created:** [September 23, 2022, 7:53pm UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720 "2022-09-23T19:53:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [September 23, 2022, 7:53pm UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720/1 "2022-09-23T19:53:08Z")

</div>

What is the best practice for go back and forth between a `NTuple{N,UInt8} where N` and a `String`?

```julia
x = "Dfsddfs"
a = ntuple(i -> i <= ncodeunits(x) ? codeunit(x,i) : 0x0, 10 + 1)
function _ntuple_to_string(x)
    r = Ref(x)
    GC.@preserve r unsafe_string(Ptr{Cchar}(pointer_from_objref(r)))
end

julia> _ntuple_to_string(a)
"Dfsddfs"

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 24, 2022, 1:16am UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720/2 "2022-09-24T01:16:10Z")

</div>

Using `unsafe_string` like this seems pretty unsafe. ( ~~For one thing, you are assuming that the tuple-data is NUL-terminated because you didn’t pass a length. I’m surprised it doesn’t crash.~~ Oh, I see, you explicitly NUL-terminated your tuple.)

I would do something like:

```julia
function ntuple_to_string(t::NTuple{N,UInt8}) where N
    b = Base.StringVector(N) # or N-1 if your tuples are NUL-terminated
    return String(b .= t) # or t[1:N-1]
end

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [September 24, 2022, 1:26am UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720/3 "2022-09-24T01:26:14Z")

</div>

We were thinking about `Base.StringVector` and the underlying `jl_alloc_string` but I noticed it’s still not exported or documented.

> <https://github.com/JuliaLang/julia/issues/19945>
>
> There are now (as of #19449) undocumented functions \`Base.\_string\_n(n)\` (to allo…cate an \`n\`-byte string) and \`Base.StringVector(n)\` (to allocate an \`n\`-byte array that can be converted to a string without copying). Should some version of these be documented and exported? They seem useful for e.g. string processing and calling C APIs expecting pre-allocated string buffers.
> 
> Note also that the \`String(v::Vector{UInt8})\` documentation, which says that it \*takes "ownership" of the array\*, seems to be wrong now (unless \`v\` was allocated with \`StringVector\`).
> 
> cc @JeffBezanson, @nalimilan

I also note that your implementation returns some extra null characters, so we might need to find the null byte and truncate the string.

```julia
julia> ntuple_to_string(a)
"Dfsddfs\0\0\0\0"

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 24, 2022, 1:44am UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720/4 "2022-09-24T01:44:00Z")

</div>

> [@mkitti](#):
>
> I also note that your implementation returns some extra null characters, so we might need to find the null byte and truncate the string.

You didn’t specify that your NTuple was NUL-terminated. Yes, replace `N` with `findfirst(iszero, t) - 1`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 24, 2022, 1:50am UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720/5 "2022-09-24T01:50:13Z")

</div>

> [@mkitti](#):
>
> We were thinking about `Base.StringVector` and the underlying `jl_alloc_string` but I noticed it’s still not exported or documented.

It’s so widely used that it might as well be…

But you could alternatively use an ordinary `Vector`, at the price of making an extra copy of the data. Or use an ordinary `Vector` with [StringViews.jl](https://github.com/JuliaStrings/StringViews.jl) to avoid the copy.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [September 27, 2022, 9:20am UTC](https://discourse.julialang.org/t/convert-a-ntuple-n-uint8-to-a-string-and-back/87720/6 "2022-09-27T09:20:17Z")

</div>

@stevengj I was feeling a bit unsatisfied with the state of this, so I decided to implement a NStrings.jl where I wrap an `AbstractString` around an `NTuple{N,UInt8}`, implementing your idea from [why not an NTuple? · Issue #6 · JuliaStrings/InlineStrings.jl · GitHub](https://github.com/JuliaStrings/InlineStrings.jl/issues/6) . It [incorporates your `ntuple_to_string`](https://github.com/mkitti/NStrings.jl/blob/742ea5049bf55bafd5da2734646defb25427f0c8/src/convert.jl#L37-L42).

> **[GitHub - mkitti/StaticStrings.jl: Fixed-length strings in Julia represented...](https://github.com/mkitti/StaticStrings.jl)**
>
> Fixed-length strings in Julia represented by NTuples - GitHub - mkitti/StaticStrings.jl: Fixed-length strings in Julia represented by NTuples
