2012-09-10 27 views
6

này:Làm thế nào tôi có thể chuyển đổi một chuỗi null chấm dứt trong một bộ đệm byte thành một chuỗi trong Go?

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

thực hiện điều này (^@ là null-byte):

go run test.go 
abc^@^@^@ 
+1

Tôi thích tiêu đề câu hỏi chi tiết của bạn. Tôi đã được underwhelmed bởi các câu hỏi nội dung văn bản sau đó mặc dù. (Nó cung cấp mã hữu ích mặc dù, tôi sẽ cung cấp cho bạn điều đó.) – Kissaki

Trả lời

5

sử dụng gói strings.

package main 

import (
    "fmt" 
    "strings" 
) 

func main() { 
    label := string([]byte{97, 98, 99, 0, 0, 0, 0}) 
    fmt.Println(strings.TrimSpace(label)) 
} 
+4

Tôi đã sử dụng 'strings.TrimRight (label," \ x00 ")', cảm ơn! – knarf

10

Lưu ý rằng câu trả lời đầu tiên sẽ chỉ hoạt động với chuỗi chỉ chạy một số 0 sau dấu chấm dứt null; tuy nhiên, một chuỗi chấm dứt null kiểu C thích hợp kết thúc tại \0 đầu tiên ngay cả khi nó được theo sau bởi rác. Ví dụ: []byte{97,98,99,0,99,99,0} phải được phân tích cú pháp là abc, không phải là abc^@cc.

Để phân tích đúng cách này, sử dụng string.Index, như sau, để tìm đầu tiên\0 và sử dụng nó để cắt gốc byte-lát:

package main 

import (
    "fmt" 
    "strings" 
) 

func main() { 
    label := []byte{97,98,99,0,99,99,0} 
    s := label[:strings.Index(string(label), "\x00")] 
    fmt.Println(string(s)) 
} 

EDIT: Được in phiên bản rút gọn như một []byte thay vì là string. Nhờ @serbaut cho việc bắt.

+2

Không phải là chuỗi (label [: bytes.IndexByte (label, 0)])? – serbaut

+0

@ serbaut, bạn rất chính xác; nên chạy nó trong khi chơi, và tôi đã nhận thấy định dạng byte []. Đã chỉnh sửa – azernik

6

Có chức năng này ẩn bên trong gói syscall của Go tìm thấy byte rỗng đầu tiên ([] byte {0}) và trả về độ dài. Tôi giả sử nó được gọi là clen cho C-Length.

Xin lỗi tôi là một năm cuối về câu trả lời này, nhưng tôi nghĩ đó là một nhiều đơn giản hơn so với hai khác (không nhập khẩu không cần thiết, vv)

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

Vì vậy,

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

Điều gì^nói là đặt s thành lát byte trong label từ đầu đến chỉ mục của clen(label).

Kết quả sẽ là abc với chiều dài 3.

+1

Đây thực sự là giải pháp sạch, đơn giản và hiệu quả nhất. –

+1

Và, không giống như câu trả lời 'string.Index', điều này sẽ không hoảng sợ nếu cung cấp' [] byte' không * không * chứa một byte không. –

0

Câu trả lời đầu tiên sẽ không hoạt động !!

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) 
} 

không có "\ x00" trong func Không gian nào cả.

+0

xem nhận xét đầu tiên của câu trả lời đó – knarf

+0

cảm ơn u, u là đúng. @knarf – wllenyj

Các vấn đề liên quan