178

How to get an "E" output rather than 69?

package main

import "fmt"

func main() {
    fmt.Print("HELLO"[1])
}

Does Golang have function to convert a char to byte and vice versa?

12 Answers 12

250

Interpreted string literals are character sequences between double quotes "" using the (possibly multi-byte) UTF-8 encoding of individual characters. In UTF-8, ASCII characters are single-byte corresponding to the first 128 Unicode characters. Strings behave like slices of bytes. A rune is an integer value identifying a Unicode code point. Therefore,

package main

import "fmt"

func main() {
    fmt.Println(string("Hello"[1]))              // ASCII only
    fmt.Println(string([]rune("Hello, 世界")[1])) // UTF-8
    fmt.Println(string([]rune("Hello, 世界")[8])) // UTF-8
}

Output:

e
e
界

Read:

Go Programming Language Specification section on Conversions.

The Go Blog: Strings, bytes, runes and characters in Go

Sign up to request clarification or add additional context in comments.

Comments

33

How about this?

fmt.Printf("%c","HELLO"[1])

As Peter points out, to allow for more than just ASCII:

fmt.Printf("%c", []rune("HELLO")[1])

3 Comments

So is there no way to program this? For example if I convert 1000000 characters to runes I would need 1000000*4 = 4000000 bytes of memory. utf-8 uses 1 byte for ascii characters. but the rune uses 4 bytes for each character. This means a huge memory savings. I'm guessing this requires in bit coding, but it's worth it for large text.
Yes. Raw unicode takes more space than UTF-8. If you want to save space, you use strings. If you want to really understand what you have, use runes. If you want to save space and understand what you have, process your data incrementally rather than reading in megabytes at a time.
You cannot index them. UTF8 characters can be different sizes so there would be no way to tell exactly where in memory the 1000th character is in a UTF8 string using an index. There is a utf8 package with a DecodeRune() function where you could parse it the data in memory manually to save memory.
19

You can also try typecasting it with string.

package main

import "fmt"

func main() {
    fmt.Println(string("Hello"[1]))
}

Comments

19

Can be done via slicing too

package main

import "fmt"

func main() {
    fmt.Print("HELLO"[1:2])
}

NOTE: This solution only works for ASCII characters.

2 Comments

this works only with one-byte encodings, try "हैलो"[:1] it gives you �
@vladkras You are correct. It only works with ASCII. For UTF-8, have a look at the approved answer. I will also edit the solution with this information.
9

Go doesn't really have a character type as such. byte is often used for ASCII characters, and rune is used for Unicode characters, but they are both just aliases for integer types (uint8 and int32). So if you want to force them to be printed as characters instead of numbers, you need to use Printf("%c", x). The %c format specification works for any integer type.

Comments

8

The general solution to interpreting a char as a string is string("HELLO"[1]).

Rich's solution also works, of course.

Comments

3

Try this to get the charecters by their index

package main

import (
      "fmt"
      "strings"
)

func main() {
   str := strings.Split("HELLO","")
    fmt.Print(str[1])
}

Comments

3

String characters are runes, so to print them, you have to turn them back into String.

fmt.Print(string("HELLO"[1]))

Comments

1

The right answer depends on the context.

The simplest solution is to convert the string to a rune slice. A rune is a single UTF-8 character. Keep in mind that this conversion is costly for your CPU as well as memory-wise.

package main

import "fmt"

func main() {
    str := "Hello, 世界"
    runeSlice := []rune(str)
    fmt.Printf("'%c'\n", runeSlice[8])
}

This could be a good solution if you frequently need to get the ith character of the same string, over and over again. In this case you'd make the conversion once, and use the same rune slice multiple times.

Normal strings are arrays of bytes. When you convert it to a rune slice, in the worst case it will take up 4 times as much memory, because a single rune is 4 bytes. This conversion also takes time. So using this solution to create a general utility function that returns the ith character of a string would be absolutely terrible. The code below works but is not a good idea.

package main

import (
    "fmt"
)

func RuneAt(s string, i int) (rune, bool) {
    runeSlice := []rune(s)
    if i >= len(runeSlice) || i < 0 {
        return 0, false
    }
    return runeSlice[i], true
}

func main() {
    str := "Hello, 世界"
    char, ok := RuneAt(str, 8)
    fmt.Printf("char: '%c', ok: %#v\n", char, ok)
}

A better solution in this case would be to use a for loop and utf8.DecodeRuneInString to iterate over the existing string to find the ith unicode character. This would not waste memory and your CPU's time to create a 4 times larger copy of the entire string. You only iterate up to the index you specified and you don't allocate any memory.

package main

import (
    "fmt"
    "unicode/utf8"
)

// Get the ith rune in s
func RuneAt(s string, i int) (rune, bool) {
    if i < 0 {
        // the index cannot be negative
        return 0, false
    }

    leftStr := s
    var j int
    for {
        result, size := utf8.DecodeRuneInString(leftStr)
        if size == 0 {
            // we've reached the end of the string
            return 0, false
        }
        if j == i {
            // we've found the character!
            return result, true
        }
        leftStr = leftStr[size:]
        j++
    }
}

func main() {
    str := "Hello, 世界"
    char, ok := RuneAt(str, 8)
    fmt.Printf("char: '%c', ok: %#v\n", char, ok)
}

Comments

0
package main
import "main"

func main(){
    str := "hello"
    fmt.Printf("%d\n", []byte(str))

    for i := 0; i < len(str); i++ {
        fmt.Printf("%v %[1]T\n", str[i])
    }
}

1 Comment

Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?
-2

Another Solution to isolate a character in a string

package main
import "fmt"

   func main() {
        var word string = "ZbjTS"

       // P R I N T 
       fmt.Println(word)
       yo := string([]rune(word)[0])
       fmt.Println(yo)

       //I N D E X 
       x :=0
       for x < len(word){
           yo := string([]rune(word)[x])
           fmt.Println(yo)
           x+=1
       }

}

for string arrays also:

fmt.Println(string([]rune(sArray[0])[0]))

// = commented line

1 Comment

Really, really bad code that will panic with Unicode input (len("cafés") > len([]rune("cafés")) and may reconvert the string on each iteration for, O(n²). Just do for _, r := range word { fmt.Printf("%c", r) }. If you really wanted to loop with an index for x := 0; x < limit; x++. Please learn the basics of a language before answering questions.
-7

The solution will be :

 package main

 import "fmt"

func main() {
  str := "HELLO"
  string(str[0])//H
  string(str[1])//E
  string(str[2])//L
  string(str[3])//L
  string(str[4])//O
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.