1

I am trying to write a function manually that capitalises the first letter of each word in a string. For example: "My dog is cute! I+love+my+dog+4ever" to "My Dog Is Cute! I+Love+My+Dog+4ever". I would be glad if you can help me.

func Capitalize(s string) string {
L := ToLower(s)
runeL := []rune(L)
len := len(runeL) - 1
Lnew := Concat(ToUpper(string(L[0])), string(runeL[1:len]))
LnewS := []rune(Lnew)
newstrings := []rune{}
for i := range LnewS {
    if IsAlpha(string(LnewS[i])) == true {
        newstrings = append(newstrings, LnewS[i])
    } else {
        newstrings = append(newstrings, LnewS[i])
        if LnewS[i+1] == rune(32) {
            newstrings = append(newstrings)
        }
        if IsLower(string(LnewS[i+1:])) {
            LnewS[i+1] = LnewS[i+1] - rune(32)
        }
    }
}
return string(newstrings)

}

elia
  • 71
  • 7
  • 3
    See [Make first letter of words uppercase in a string](https://stackoverflow.com/a/40382340/5728991) , [How to capitalize the first letter of a string](https://stackoverflow.com/a/70259366/5728991). –  Dec 09 '21 at 01:00
  • I edited now. Thank you for your help. I am not allowed to use functions like title. I started coding one week ago. Sorry in advance if what I wrote is complete nonsense. – elia Dec 09 '21 at 01:09
  • Could you please check my code again? this time it works but it doesn't print the last character of the string. – elia Dec 09 '21 at 03:21

3 Answers3

2

How to capitalise first letter of each word in a string in Go manually?


In a letter to Robert Hooke in 1675, Isaac Newton made his most famous statement: “If I have seen further it is by standing on the shoulders of Giants”.

Let's follow Newton's advice and read,

The C Programming Language, Second Edition
Brian W. Kernighan and Dennis M. Ritchie

In particular, read,

1.5.4 Word Counting

The section introduces a key concept, state variables: "The variable state records whether the program is currently in a word or not."


If we apply that insight to your problem then we get something like this,

package main

import (
    "fmt"
    "unicode"
)

func Capitalize(s string) string {
    rs := []rune(s)
    inWord := false
    for i, r := range rs {
        if unicode.IsLetter(r) || unicode.IsNumber(r) {
            if !inWord {
                rs[i] = unicode.ToTitle(r)
            }
            inWord = true
        } else {
            inWord = false
        }
    }
    return string(rs)
}

func main() {
    s := "My dog is cute! I+love+my+dog+4ever"
    fmt.Println(s)
    t := Capitalize(s)
    fmt.Println(t)
}

https://go.dev/play/p/4QnHIqfGjWy

My dog is cute! I+love+my+dog+4ever
My Dog Is Cute! I+Love+My+Dog+4ever

Unicode: Character Properties, Case Mappings & Names FAQ

The titlecase mapping in the Unicode Standard is the mapping applied to the initial character in a word.

rocka2q
  • 2,473
  • 4
  • 11
1

You can use the strings package with its title function to capitalize first letter of each word. An example of it can be seen below.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)


func main() {
    var strInput string
    fmt.Println("Enter a string")
    scanner := bufio.NewScanner(os.Stdin)
    if scanner.Scan() {
        strInput = scanner.Text()
    }

    res := strings.Title(strInput)
    fmt.Println(res)
}

If you wanna do it manually, write an algorithm where

  • Checks the entire index of the string
  • If an index is the first index or it's an alphabet after a space, change that index alphabet into uppercase, and it should work
Amodh
  • 367
  • 1
  • 3
  • 16
  • 1
    Thank you for your answer Amodh! but I am not allowed to use strings package. I need to write a function works as Title function manually. I cannot figure out how I should write. – elia Dec 09 '21 at 01:19
  • FWIW strings.Title() is deprecated in 1.18 https://github.com/golang/go/issues/48367 – Jobu Apr 14 '22 at 19:34
  • 1
    It seems `cases.Title(language.AmericanEnglish, cases.NoLower).String(s)` would do similar. – Jobu Apr 14 '22 at 19:41
0

strings.Title() has been deprecated. It is recommended that you use golang.org/x/text/cases instead. However, the results do not produce the desired output by the OP.

cases.Title Example

Run the following command in your terminal...

go get golang.org/x/text

Then you can capitalize each word in a string like this...

package main

import (
    "fmt"
    "golang.org/x/text/cases"
    "golang.org/x/text/language"
)

func main() {
    input := "My dog is cute! I+love+my+dog+4ever"
    output := cases.Title(language.English).String(input)
    fmt.Printf(" input=%s\n, output=%s\n", input, output)
}

Result

 input=My dog is cute! I+love+my+dog+4ever
output=My Dog Is Cute! I+Love+My+Dog+4Ever
                                      ^
OP wants '4ever' not '4Ever'

cases.Title Note 1

This will also turn all uppercase words to only have the first letter uppercase. E.g. USA will become Usa. You will need to pass cases.NoLower to void this behavior.

func main() {
    input := "the USA"
    output := cases.Title(language.English, cases.NoLower).String(input)
    fmt.Printf(" input=%s\n, output=%s\n", input, output)
}

// Result = "The USA"

cases.Title Note 2

cases.Title does not handle abbreviated English ordinal numbers well. For example, 10th will be transformed to 10Th and 3rd will be transformed to 3Rd.

Daniel Morell
  • 2,308
  • 20
  • 34