从julia中的字节向量读取以null结尾的字符串

问题描述 投票:1回答:3

我有一个类型为UInt8且固定长度为10的向量。我认为它包含一个以Null结尾的字符串,但是当我执行String(v)时,它将显示字符串+该向量其余部分的所有零。

v = zeros(UInt8, 10)
v[1:5] = Vector{UInt8}("hello")
String(v)

输出为“ hello \ 0 \ 0 \ 0 \ 0 \ 0”。

要么我打包错了,要么读错了。有什么想法吗?

julia c-strings null-terminated
3个回答
3
投票

我使用此代码段:

"""
    nullstring(Vector{UInt8})
Interpret a vector as null terminated string.
"""
nullstring(x::Vector{UInt8}) = String(x[1:findfirst(==(0), x) - 1])

尽管我敢打赌,有更快的方法可以做到这一点。


2
投票

您可以使用unsafe_stringunsafe_string(pointer(v)),此操作无需复制,因此非常快。但是@laborg的解决方案在几乎所有情况下都更好,因为它是安全的。如果要兼顾安全和最佳性能,则必须自己编写一个手动功能:

function get_string(v::Vector{UInt8})
    # Find first zero
    zeropos = 0
    @inbounds for i in eachindex(v)
        iszero(v[i]) && (zeropos = i; break)
    end
    iszero(zeropos) && error("Not null-terminated")
    GC.@preserve v unsafe_string(pointer(v), zeropos - 1)
end

但是,你真的需要这么快的几率。


1
投票

您可以使用以下代码避免复制字节并保持安全性:

function nullstring!(x::Vector{UInt8})
    i = findfirst(iszero, x)
    SubString(String(x),1,i-1)
end

请注意,在调用x后,x将为空,返回值为Substring而不是String,但在许多情况下都没有关系。该代码比@laborg的代码分配一半,并且速度稍快(大约10-20%)。尽管Jacob的代码仍然无与伦比。

© www.soinside.com 2019 - 2024. All rights reserved.