-2

Please help me write a function that takes input of a string and a number and outputs a shortened string to the number + "...". If the string does not exceed the size (number), then just output this string, but without the "...". Also, our string uses only single-byte characters and the number is strictly greater than zero.

My two attempts:

package main

import (
        "fmt"
)
func main() {
var text string
var width int
fmt.Scanf("%s %d",&text,&width)
res := text[:width]
fmt.Println(res+"...")
}

But this function adds "..." even if the string does not exceed the width.

package main
import (
        "fmt"
)
var text string
var width int
fmt.Scanf("%s %d",&text,&width)
if width <= 0 {
    fmt.Println("")
}
res := ""
count := 0
for _, char := range text {
res += string(char)
    count++
    if count >= width {
        break
    }
}
fmt.Println(res+"...")
}

This function works the same way.

Biffen
  • 6,249
  • 6
  • 28
  • 36
  • 3
    The easiest would be to convert the string to `[]rune`, so you can check how many runes it has. Only slice it and append `...` if it's greater than the limit. – icza Oct 11 '21 at 14:37
  • dup with good answers https://stackoverflow.com/questions/46415894/golang-truncate-strings-with-special-characters-without-corrupting-data –  Oct 16 '21 at 09:36

3 Answers3

1

To continue with what @Marcelloh said

Here's an example of using runes instead of bytes.

package main

import (
    "fmt"
)

func Truncate(text string, width int) (string, error) {
    if width < 0 {
        return "", fmt.Errorf("invalid width size")
    }
    
    r := []rune(text)
    trunc := r[:width]
    return string(trunc)+ "...", nil
}

func main() {
    word, err := Truncate("Hello, World", 3)
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(word)
    // Output: Hel...
}
Anthony Gedeon
  • 354
  • 4
  • 12
0

Just a basic example that can get you going :-)

func main() {
    var text string
    var width int = 12
    text = "a ver long string of text to be shortened"
    if len(text) > width {
        text = string([]byte(text)[:width])

    }
    fmt.Println(text + "...")
}

Of course, you need to read about runes, and some "strings" have a length of 3, while you see only one. But for normal ASCII, the above would do the trick.

Marcelloh
  • 82
  • 1
  • 5
  • I have plussed, but please add a comment about the matters about why runes, bytes etc https://play.golang.org/p/ayMp_gpRrag –  Oct 16 '21 at 09:23
  • Look at this to understand why runes are a bit different in their length: https://goplay.space/#fSmFO6SLIDQ – Marcelloh Oct 18 '21 at 06:34
-1
package main

import (
    "fmt"
)

func main(){
    var text string
    var width int
    fmt.Scanf("%s %d",&text,&width)
    res := []rune(text)
    if len(res) > width {
        res = res[:width]
        fmt.Println(string(res)+"...")
    } else {
        fmt.Println(string(res))
    }
}
Ryan M
  • 18,333
  • 31
  • 67
  • 74