#BEGINNER - Acting weird when using special characters

50 messages · Page 1 of 1 (latest)

viscid thistle
#

import (
    "fmt"
)

func Rotate(s string) []string {
    slice := make([]string, len(s))
    for i := range s {
        slice[i] = s[i:] + s[:i]
    }
    return slice
}

func main() {
    var input string
    fmt.Scan(&input)
    slice := Rotate(input)

    for _, element := range slice {
        fmt.Println(element)
    }
}```

The following code is supposed to rotate the first character to the last position and execute evert possible rotation, it works fine with the "normal letters" ( letters of the Latin alphabet ) but puts some unexpected new lines when using non-European letters such as "ŽǯƅƅŦŘ" and I was wondering why this occurs?
tawdry forge
#

Try checking the byte format of such character, it may be because there are more than one character at the same place

summer dock
#

if you change your approach to use append instead of direct assignment you will see the expected results.

#

Note that the underlying issue of "a character is not a byte" is still there, there are "characters" that can be comprised of multiple code points

viscid thistle
summer dock
#

for instance is encoded as 3 bytes, so if the string were a€b you'd see 0, 1, 4 where 0 is the start of a, 1 is the start of and 4 is the start of b

viscid thistle
#
    slice := make([]string, len(s))
    for i := 0; i < len(s); i++ {
        slice[i] = s[i:] + s[:i]
    }
    return slice
}```
summer dock
#

that's more incorrect

finite spade
#

wow discord scrolled at once

viscid thistle
# summer dock see this
    slice := make([]string, len(s))
    for i := range s {
        slice = append(slice, s[i:]+s[:i])
    }
    return slice
}```
#

this way?

summer dock
viscid thistle
#
    var slice []string
    for i := range s {
        slice = append(slice, s[i:]+s[:i])
    }
    return slice
}```
#

like this works fine

summer dock
#

exactly

viscid thistle
#

hmmmmm

#

maybe it's a dumb thought but it makes me wonder why using slice := make([]string, len(s)) instead of var slice []string

#

like not only in this particulare context but in general while programming in Go

#

if I'm saying stupid stuff don't mind me, I've just came back from an exam

#

and my mind is not working good

summer dock
#

creating a slice with a >0 length or capacity is usually a matter of efficiency.
append may need to re-allocate the slice's backing array if it is too small to add another element, this is sometimes undesirable

viscid thistle
#

if you've already explained it just ignore the message

summer dock
#

you could do direct assignment, but you'd have to manage the index variable yourself

crimson glacier
#

something like this

func Rotate(s string) []string {
    l := len(s)
    j := l - 1
    slice := make([]string, l)
    for i, val := range s {
        slice[j-i] = string(val)
    }
    return slice
}

ah, range also returns the value in that position.

#

and this Ž letters have their own data type and it is called rune in go.

viscid thistle
#

did you try the code?

crimson glacier
#

yep

#

you wanted to invert ?

viscid thistle
#

ŽǯƅƅŦŘ
ǯƅƅŦŘŽ
ƅƅŦŘŽǯ
ƅŦŘŽǯƅ
ŦŘŽǯƅƅ
ŘŽǯƅƅŦ

#

this is what I've wanted as output

#

your code does something else

summer dock
crimson glacier
#
func Rotate(s string) []string {
    l := len(s)
    slice := make([]string, l)
    for i, val := range s {
        if i == 0 {
            slice[l-1] = string(val)
            continue
        }
        slice[i-1] = string(val)
    }
    return slice
}

this works

summer dock
#

it does not

#

the length of a string is the amount of bytes it encodes as, not the number of code points it contains

summer dock
#

I'd encourage you both to read https://go.dev/blog/strings it goes into a fair bit of detail about the intricacies of characters, strings, unicode etc

crimson glacier
summer dock
#

you're just hiding it with strings.Join

#

given this has led to an unprompted discussion this is a correct, albeit not recommended by me, solution go func Rotate(s string) []string { slice := make([]string, len(s)) var n int for i := range s { slice[n] = s[i:] + s[:i] n++ } return slice[:n] }
My recommendation remains: use append