0으로 끝나는 바이트 배열을 문자열로 변환하는 방법은 무엇입니까?
[100]byte
많은 string
데이터 를 전송 하기 위해 읽어야 합니다 .
모든 string
s의 길이가 정확히 100자인 것은 아니므로 나머지 부분은 s byte array
로 채워집니다 0
.
내가 tansfer 경우 [100]byte
에 string
기준 : string(byteArray[:])
의 미행 0
들로 표시됩니다 ^@^@
의.
C에서는 string
의지 가 끝나기 때문에 Golang에서 0
a byte array
를 현명하게 전환하는 가장 좋은 방법이 무엇인지 궁금합니다 string
.
바이트 슬라이스로 데이터를 읽는 메소드는 읽은 바이트 수를 리턴합니다. 해당 번호를 저장 한 다음이를 사용하여 문자열을 작성해야합니다. n
읽은 바이트 수이므로 코드는 다음과 같습니다.
s := string(byteArray[:n])
어떤 이유로 든이없는 경우 n
입력에 null 문자가 없다고 가정하면 bytes 패키지를 사용하여 찾을 수 있습니다.
n := bytes.Index(byteArray, []byte{0})
또는 icza가 지적했듯이 아래 코드를 사용할 수 있습니다.
n := bytes.IndexByte(byteArray, 0)
는 어때?
s := string(byteArray[:])
간단한 솔루션 :
str := fmt.Sprintf("%s", byteArray)
나는 이것이 얼마나 성능이 있는지 잘 모르겠습니다.
예를 들어
package main
import "fmt"
func CToGoString(c []byte) string {
n := -1
for i, b := range c {
if b == 0 {
break
}
n = i
}
return string(c[:n+1])
}
func main() {
c := [100]byte{'a', 'b', 'c'}
fmt.Println("C: ", len(c), c[:4])
g := CToGoString(c[:])
fmt.Println("Go:", len(g), g)
}
산출:
C: 100 [97 98 99 0]
Go: 3 abc
다음 코드는 '\ 0'을 찾고 있으며 질문의 가정에 따라 '\ 0'이 아닌 모든 '\ 0'이 앞에 오므로 배열을 정렬 된 것으로 간주 할 수 있습니다. 배열이 데이터 내에 '\ 0'을 포함 할 수 있으면이 가정은 유지되지 않습니다.
이진 검색을 사용하여 첫 번째 0 바이트의 위치를 찾은 다음 슬라이스하십시오.
다음과 같이 0 바이트를 찾을 수 있습니다.
package main
import "fmt"
func FirstZero(b []byte) int {
min, max := 0, len(b)
for {
if min + 1 == max { return max }
mid := (min + max) / 2
if b[mid] == '\000' {
max = mid
} else {
min = mid
}
}
return len(b)
}
func main() {
b := []byte{1, 2, 3, 0, 0, 0}
fmt.Println(FirstZero(b))
}
특히 대부분의 문자열이 짧은 경우 바이트 배열을 순전히 스캔하여 0 바이트를 찾는 것이 더 빠를 수 있습니다.
배열에서 0이 아닌 바이트가 아닌 정확한 길이를 모르면 먼저 트리밍 할 수 있습니다.
문자열 (bytes.Trim (arr, "\ x00"))
성능 조정에만 사용하십시오.
package main
import (
"fmt"
"reflect"
"unsafe"
)
func BytesToString(b []byte) string {
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := reflect.StringHeader{bh.Data, bh.Len}
return *(*string)(unsafe.Pointer(&sh))
}
func StringToBytes(s string) []byte {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{sh.Data, sh.Len, 0}
return *(*[]byte)(unsafe.Pointer(&bh))
}
func main() {
b := []byte{'b', 'y', 't', 'e'}
s := BytesToString(b)
fmt.Println(s)
b = StringToBytes(s)
fmt.Println(string(b))
}
왜 안돼?
bytes.NewBuffer(byteArray).String()
읽기 대신 배열 대신 슬라이스를 사용하십시오. 예를 들어
io.Reader
배열이 아닌 슬라이스를 허용합니다.제로 패딩 대신 슬라이싱을 사용하십시오.
예:
buf := make([]byte, 100)
n, err := myReader.Read(buf)
if n == 0 && err != nil {
log.Fatal(err)
}
consume(buf[:n]) // consume will see exact (not padded) slice of read data
공황 상태에 빠졌을 때 몇 가지 방법을 시도했습니다.
런타임 오류 : 슬라이스 범위를 벗어났습니다.
그러나 이것은 마침내 효과가있었습니다.
string(Data[:])
더 빠른 방법은 다음과 같습니다.
resp, _ := http.Get("https://www.something.com/something.xml")
bytes, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
fmt.Println(string(bytes)) //just convert with string() function
재귀 적 솔루션을 사용하는 경우
func CToGoString(c []byte, acc string) string {
if len(c) == 0 {
return acc
} else {
head := c[0]
tail := c[1:]
return CToGoString(tail, acc + fmt.Sprintf("%c", head))
}
}
func main() {
b := []byte{some char bytes}
fmt.Println(CToGoString(b, ""))
}
참고 URL : https://stackoverflow.com/questions/14230145/how-to-convert-a-zero-terminated-byte-array-to-string
'development' 카테고리의 다른 글
WCF 대 ASP.NET 웹 API (0) | 2020.02.14 |
---|---|
현재 지점에 대한 추적 정보가 없습니다 (0) | 2020.02.14 |
요소에 JavaScript의 클래스가 포함되어 있는지 확인 하시겠습니까? (0) | 2020.02.14 |
예외를 던질 때 JavaScript 스택 추적을 어떻게 얻을 수 있습니까? (0) | 2020.02.14 |
Cassandra의 파티션 키, 복합 키 및 클러스터링 키의 차이점은 무엇입니까? (0) | 2020.02.14 |