8

これ:

label := string([]byte{97, 98, 99, 0, 0, 0, 0})
fmt.Printf("%s\n", label)

これ^@を行います(ヌルバイトです):

go run test.go 
abc^@^@^@
4

5 に答える 5

15

Goのsyscallパッケージ内に隠されているこの関数は、最初のnullバイト([] byte {0})を見つけて、長さを返します。C-Lengthのクレンと呼ばれていると思います。

申し訳ありませんが、この回答は1年遅れていますが、他の2つよりもはるかに簡単だと思います(不要なインポートなどはありません)。

func clen(n []byte) int {
    for i := 0; i < len(n); i++ {
        if n[i] == 0 {
            return i
        }
    }
    return len(n)
}

それで、

label := []byte{97, 98, 99, 0, 0, 0, 0}
s := label[:clen(label)]
fmt.Println(string(s))

^が言うことは、最初からのインデックスまでのsバイトのスライスに設定することです。labelclen(label)

結果はabc3の長さになります。

于 2015-01-08T07:19:24.600 に答える
12

最初の答えは、ヌルターミネータの後にゼロが実行されるだけの文字列でのみ機能することに注意してください。ただし、適切なCスタイルのnullで終了する文字列は、\0その後にガベージが続く場合でも、最初に終了します。たとえば、はではなく、[]byte{97,98,99,0,99,99,0}として解析する必要があります。abcabc^@cc

これを適切に解析するには、次のように、を使用して最初string.Indexのものを見つけ、それを使用して元のバイトスライスをスライスします。 \0

package main

import (
    "fmt"
    "strings"
)

func main() {
    label := []byte{97,98,99,0,99,99,0}
    nullIndex := strings.Index(string(label), "\x00")
    if (nullIndex < 0) {
        fmt.Println("Buffer did not hold a null-terminated string")
        os.Exit(1)
    }
    fmt.Println(string(label[:nullIndex]))
}

編集:短縮版をでは[]byteなくとして印刷していましたstring。キャッチしてくれた@serbautに感謝します。

編集2:ヌルターミネータのないバッファのエラーケースを処理していませんでした。キャッチしてくれた@snapに感謝します。

于 2012-09-11T20:36:22.857 に答える
3

stringsパッケージを使用してください。

package main

import (
    "fmt"
    "strings"
)

func main() {
    label := string([]byte{97, 98, 99, 0, 0, 0, 0})
    fmt.Println(strings.TrimSpace(label))
}
于 2012-09-10T21:34:40.800 に答える
1

sysパッケージを使用できます:

package main
import "golang.org/x/sys/windows"

func main() {
   b := []byte{97, 98, 99, 0, 0, 0, 0}
   s := windows.ByteSliceToString(b)
   println(s == "abc")
}

または、自分で実装することもできます。

package main
import "bytes"

func byteSliceToString(s []byte) string {
   n := bytes.IndexByte(s, 0)
   if n >= 0 {
      s = s[:n]
   }
   return string(s)
}

func main() {
   b := []byte{97, 98, 99, 0, 0, 0, 0}
   s := byteSliceToString(b)
   println(s == "abc")
}
于 2021-04-22T18:08:19.813 に答える
-1

最初の答えはうまくいきません!!

func TrimSpace(s []byte) []byte {
    return TrimFunc(s, unicode.IsSpace)
}

func IsSpace(r rune) bool {
    // This property isn't the same as Z; special-case it.
    if uint32(r) <= MaxLatin1 {
        switch r {
        case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
            return true
        }
        return false
    }
    return isExcludingLatin(White_Space, r)
}

funcIsSpaceには「\x00」はまったくありません。

于 2017-03-24T06:42:23.083 に答える