How to convert uint8 to string - go

I want to convert uint8 to string but can't figure out how.
package main
import "fmt"
import "strconv"
func main() {
str := "Hello"
fmt.Println(str[1]) // 101
fmt.Println(strconv.Itoa(str[1]))
}
Example
This gives me prog.go:11: cannot use str[1] (type uint8) as type int in function argument [process exited with non-zero status]
Any idea?

Simply convert it :
fmt.Println(strconv.Itoa(int(str[1])))

There is a difference between converting it or casting it, consider:
var s uint8 = 10
fmt.Print(string(s))
fmt.Print(strconv.Itoa(int(s)))
The string cast prints '\n' (newline), the string conversion prints "10". The difference becomes clear once you regard the []byte conversion of both variants:
[]byte(string(s)) == [10] // the single character represented by 10
[]byte(strconv.Itoa(int(s))) == [49, 48] // character encoding for '1' and '0'
see this code in play.golang.org

You can do it even simpler by using casting, this worked for me:
var c uint8
c = 't'
fmt.Printf(string(c))

There are no automatic conversions of basic types in Go expressions. See https://talks.golang.org/2012/goforc.slide#18. A byte (an alias of uint8) or []byte ([]uint8) has to be set to a bool, number or string.
package main
import (
. "fmt"
)
func main() {
b := []byte{'G', 'o'}
c := []interface{}{b[0], float64(b[0]), int(b[0]), rune(b[0]), string(b[0]), Sprintf("%s", b), b[0] != 0}
checkType(c)
}
func checkType(s []interface{}) {
for k, _ := range s {
// uint8 71, float64 71, int 71, int32 71, string G, string Go, bool true
Printf("%T %v\n", s[k], s[k])
}
}
Sprintf("%s", b) can be used to convert []byte{'G', 'o' } to the string "Go". You can convert any int type to a string with Sprintf. See https://stackoverflow.com/a/41074199/12817546.
But Sprintf uses reflection. See the comment in https://stackoverflow.com/a/22626531/12817546. Using Itoa (Integer to ASCII) is faster. See #DenysSéguret and https://stackoverflow.com/a/38077508/12817546. Quotes edited.

use %c
str := "Hello"
fmt.Println(str[1]) // 101
fmt.Printf("%c\n", str[1])

Related

Unable to convert my string to hex message

Below has x which is my expected string
I am trying to recreate y myself to match my expected string. Basically trying to convert "01" to "\x01" so that I get the same byte when printed.
Now when I print []byte(x) and []byte(y) I want them to be the same but they aren't. Please help me recreate x with "01" as my input.
package main
import (
"fmt"
)
func main() {
//Expected string
x := "\x01"
//Trying to convert my 01 in string form to same as above - Basically recreate above string again
y := "\\x" + "01"
fmt.Println(x)
fmt.Println(y)
fmt.Println([]byte(x))
fmt.Println([]byte(y))
}
This is what i wanted - got my issue resolved ! :) Thanks all
import (
"fmt"
"encoding/hex"
)
func main() {
//Expected string
x := "\x01"
//Trying to convert my 01 in string form to same as above - Basically recreate above string again
y,err := hex.DecodeString("01")
if err != nil {
panic(err)
}
fmt.Println(x)
fmt.Println(y)
fmt.Println([]byte(x))
fmt.Println([]byte(y))
}
You cannot build a string from a byte sequence that way... \x01 is an escaping notation processed by the compiler when reading literal strings, you cannot use that processing at runtime.
To build a string with the bytes you want you can simply use
x := string([]byte{1, 2, 3, 4})

How to omit conditional field of struct within marshal

There is struct of MyStruct.
type MyStruct struct {
Code int `json:"Code"`
Flags uint8 `json:"Flags"`
OptionField int `json:",omitempty"`
}
Following code convert it to json.
f := MyStruct{Code:500, OptionField:41}
r, _ := json.Marshal(f)
fmt.Println(string(r)
I need to "OptionField" be optional. Some time it should exist in json with one of values [0, 1, 2, 3, ]. and in the other time it should exclude from json.
My problem is: omitempty will exclude it when the value is zero, and the default value of int is zero. Is there any way to omit field in condition (ex: omit if value is -1). Or there is any way to do it.
You could use *int instead of int and set the pointer value to nil in order to omit this.
package main
import (
"encoding/json"
"fmt"
)
type MyStruct struct {
Code int `json:"Code"`
Flags uint8 `json:"Flags"`
OptionField *int `json:",omitempty"`
}
func format(s MyStruct) string {
r, _ := json.Marshal(s)
return string(r)
}
func main() {
f := MyStruct{Code: 500, Flags: 10, OptionField: new(int)}
fmt.Println(format(f)) // {"Code":500,"Flags":10,"OptionField":0}
f.OptionField = nil
fmt.Println(format(f)) // {"Code":500,"Flags":10}
}

Convert uint16 array to string

I have an array of uint16 coming from WinAPI PROCESSENTRY32.szExeFile that I wanna convert to a string.
Here's my var type
var hello [260]uint16
now I need to convert hello to a string. How can I do that?
Edit
Here's what I've tried:
func szExeFileToString(ByteString [260]uint16) string {
b := make([]byte, len(ByteString))
for i, v := range ByteString {
b[i] = byte(v)
}
return string(b)
}
However, this returns pretty weird strings...
result (the function should convert Windows process names in the PROCESSENTRY32.szExeFile (-> [260]uint16) type to string)
package windows
import "golang.org/x/sys/windows"
func UTF16ToString
func UTF16ToString(s []uint16) string
UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
with a terminating NUL removed.
Use windows.UTF16ToString. For example,
package main
import (
"fmt"
"golang.org/x/sys/windows"
)
func main() {
var szExeFile [260]uint16
szExeFile = [260]uint16{'e', 'x', 'e', 'F', 'i', 'l', 'e'}
exeFile := windows.UTF16ToString(szExeFile[:])
fmt.Println(exeFile)
}
Output:
exeFile
Fixed it. Here's the fixed function to help anyone that gets into this question to convert PROCESSENTRY32.szExeFile result to a string.
Note: I've also forgot to use kernel32.NewProc("Process32FirstW") and kernel32.NewProc("Process32NextW") instead of kernel32.NewProc("Process32First")
func szExeFileToString(ByteString [260]uint16) string {
var End = 0
for i, _ := range ByteString {
if ByteString[i] == 0 {
End = i
break
}
}
return syscall.UTF16ToString(ByteString[:End])
}

string to big Int in Go?

Is there a way to convert a string (which is essentially a huge number) from string to Big int in Go?
I tried to first convert it into bytes array
array := []byte(string)
Then converting the array into BigInt.
I thought that worked, however, the output was different than the original input. So I'm guessing the conversion didn't do the right thing for some reason.
The numbers I'm dealing with are more than 300 digits long, so I don't think I can use regular int.
Any suggestions of what is the best approach for this?
Package big
import "math/big"
func (*Int) SetString
func (z *Int) SetString(s string, base int) (*Int, bool)
SetString sets z to the value of s, interpreted in the given base, and
returns z and a boolean indicating success. The entire string (not
just a prefix) must be valid for success. If SetString fails, the
value of z is undefined but the returned value is nil.
The base argument must be 0 or a value between 2 and MaxBase. If the
base is 0, the string prefix determines the actual conversion base. A
prefix of “0x” or “0X” selects base 16; the “0” prefix selects base 8,
and a “0b” or “0B” prefix selects base 2. Otherwise the selected base
is 10.
For example,
package main
import (
"fmt"
"math/big"
)
func main() {
n := new(big.Int)
n, ok := n.SetString("314159265358979323846264338327950288419716939937510582097494459", 10)
if !ok {
fmt.Println("SetString: error")
return
}
fmt.Println(n)
}
Playground: https://play.golang.org/p/ZaSOQoqZB_
Output:
314159265358979323846264338327950288419716939937510582097494459
See Example for string to big int conversion.
package main
import (
"fmt"
"log"
"math/big"
)
func main() {
i := new(big.Int)
_, err := fmt.Sscan("18446744073709551617", i)
if err != nil {
log.Println("error scanning value:", err)
} else {
fmt.Println(i)
}
}
Output:
18446744073709551617

Text processing in Go - how to convert string to byte?

I'm writing a small pragram to number the paragraph:
put paragraph number in front of each paragraph in the form of [1]..., [2]....
Article title should be excluded.
Here is my program:
package main
import (
"fmt"
"io/ioutil"
)
var s_end = [3]string{".", "!", "?"}
func main() {
b, err := ioutil.ReadFile("i_have_a_dream.txt")
if err != nil {
panic(err)
}
p_num, s_num := 1, 1
for _, char := range b {
fmt.Printf("[%s]", p_num)
p_num += 1
if char == byte("\n") {
fmt.Printf("\n[%s]", p_num)
p_num += 1
} else {
fmt.Printf(char)
}
}
}
http://play.golang.org/p/f4S3vQbglY
I got this error:
prog.go:21: cannot convert "\n" to type byte
prog.go:21: cannot convert "\n" (type string) to type byte
prog.go:21: invalid operation: char == "\n" (mismatched types byte and string)
prog.go:25: cannot use char (type byte) as type string in argument to fmt.Printf
[process exited with non-zero status]
How to convert string to byte?
What is the general practice to process text? Read in, parse it by byte, or by line?
Update
I solved the problem by converting the buffer byte to string, replacing strings by regular expression. (Thanks to #Tomasz Kłak for the regexp help)
I put the code here for reference.
package main
import (
"fmt"
"io/ioutil"
"regexp"
)
func main() {
b, err := ioutil.ReadFile("i_have_a_dream.txt")
if err != nil {
panic(err)
}
s := string(b)
r := regexp.MustCompile("(\r\n)+")
counter := 1
repl := func(match string) string {
p_num := counter
counter++
return fmt.Sprintf("%s [%d] ", match, p_num)
}
fmt.Println(r.ReplaceAllStringFunc(s, repl))
}
Using "\n" causes it to be treated as an array, use '\n' to treat it as a single char.
A string cannot be converted into a byte in a meaningful way. Use one of the following approaches:
If you have a string literal like "a", consider using a rune literal like 'a' which can be converted into a byte.
If you want to take a byte out of a string, use an index expression like myString[42].
If you want to interpret the content of a string as a (decimal) number, use strconv.Atoi() or strconv.ParseInt().
Please notice that it is customary in Go to write programs that can deal with Unicode characters. Explaining how to do this would be too much for this answer, but there are tutorials out there which explain what kind of things to pay attention to.

Resources