Necesito leer [100]bytepara transferir un montón de stringdatos.
Debido a que no todos los strings tienen exactamente 100 caracteres de largo, la parte restante del mismo byte arrayse rellena con 0s.
Si convierto [100]bytea stringby:, string(byteArray[:])los 0s de cola se muestran como ^@^@s.
En la C stringse terminará con 0, por lo que me pregunto ¿cuál es la mejor manera de convertir esta byte arraya stringen Golang.

^@no se muestra, pero hubiera estado allí si lo probaras en la terminal o algo similar. La razón de esto es que Go no deja de convertir la matriz de bytes en una cadena cuando encuentra un 0.len(string(bytes))en su ejemplo es 5 y no 1. Depende de la función de salida, si la cadena está totalmente (con ceros) impresa o no.string(body).Respuestas:
Los métodos que leen datos en segmentos de bytes devuelven el número de bytes leídos. Debe guardar ese número y luego usarlo para crear su cadena. Si
nes el número de bytes leídos, su código se vería así:Para convertir la cadena completa, esto se puede usar:
Esto es equivalente a:
Si por alguna razón no lo sabe
n, puede usar elbytespaquete para encontrarlo, suponiendo que su entrada no tenga un carácter nulo incrustado.O como señaló icza, puede usar el siguiente código:
fuente
bytes.IndexByte()qué búsquedas para un solo enbytelugar debytes.Index()con un segmento de bytes que contiene 1 byte.¿Qué pasa?
fuente
string(byteArray[:])contiene^@caracteresstring(byteArray)? ¿Por qué necesitas copiar la matriz usando[:]?[:], para los conjuntos de bytes, sí.Solución simplista:
Sin embargo, no estoy seguro de cuán eficiente es esto.
fuente
Por ejemplo,
Salida:
fuente
El siguiente código busca '\ 0', y bajo los supuestos de la pregunta, la matriz se puede considerar ordenada ya que todos los que no son '\ 0' preceden a todos '\ 0'. Esta suposición no se mantendrá si la matriz puede contener '\ 0' dentro de los datos.
Encuentre la ubicación del primer byte cero usando una búsqueda binaria, luego corte.
Puede encontrar el byte cero de esta manera:
Puede ser más rápido escanear ingenuamente la matriz de bytes en busca del byte cero, especialmente si la mayoría de sus cadenas son cortas.
fuente
[]byte{0}. En este caso,FirstZero()debería regresar0así cuando el resultado de corte sería"", pero en su lugar, regresa1y los resultados de corte en"\x00".Cuando no conoce la longitud exacta de bytes no nulos en la matriz, puede recortarla primero:
fuente
bytes.Trimtoma un segmento, no una matriz (lo que necesitaríaarr[:]si arr es realmente a[100]bytecomo dice la pregunta). b)bytes.Trimes la función incorrecta para usar aquí. Para una entrada como[]byte{0,0,'a','b','c',0,'d',0}esta devolverá "abc \ x00d" en lugar de "" c) ya existe una respuesta correcta que utilizabytes.IndexByte, la mejor manera de encontrar el primer byte cero.¿Por qué no esto?
fuente
byteArray[:]ya quebytes.NewBuffertoma a[]byte; b) la pregunta decía que la matriz tiene ceros finales con los que no se trata; c) si, en cambio, su variable es a[]byte(la única forma en que se compilará su línea), entonces su línea es solo una forma lenta de hacerlostring(v).Solo se usa para ajuste de rendimiento.
fuente
stringpuede tener serias implicaciones si luego se modifica el segmento de bytes.stringlos valores en Go se definen como inmutables, sobre los cuales se basan todo el tiempo de ejecución y las bibliotecas de Go. Te teletransportarás a la mitad de los errores y errores de tiempo de ejecución más misteriosos si sigues este camino.Use rebanadas en lugar de matrices para leer. por ejemplo,
io.Readeracepta un segmento, no una matriz.Use rebanado en lugar de cero relleno.
Ejemplo:
fuente
s := a[:n]os := string(a[:n])si necesita una cadena. Sinno está directamente disponible, debe calcularse, por ejemplo, buscando un byte específico / cero en el búfer (matriz) como sugiere Daniel.Probé algunos métodos pocas veces me entró el pánico:
Pero esto finalmente funcionó.
string(Data[:])fuente
Aunque no es extremadamente eficiente, la única solución legible es
Ejemplo completo para tener una matriz de bytes de estilo C:
Ejemplo completo para tener una cadena de estilo ir excluyendo los nulos:
Esto asigna una porción de porción de bytes. Por lo tanto, vigile el rendimiento si se usa en gran medida o repetidamente.
fuente
Aquí está el código para comprimir la matriz de bytes a una cadena
fuente
Aquí está la forma más rápida:
fuente
fmt, es más rápido hacerfmt.Printf("%s", bytes)que usarstring(bytes)).Yo cuando con una solución recursiva.
fuente
fmt.Println(CToGoString([]byte("ctogo\x00\x00"), "") == "ctogo")debe imprimirtrue, imprimefalse.[100]bytesino a[]byte, y no elimina'\x00'bytes. Su velocidad (depende de la entrada) es más lenta en múltiples órdenes de magnitud en comparación con la velocidad de la respuesta aceptada.