I am trying to check if a text file contains a certain word. However it will return true even for some letters in a string. For example:
Entered string: gdo
Computer found: kingdom
var word = strings.ToLower(string(a))
// read the whole file at once
b, err := ioutil.ReadFile("words.txt")
if err != nil {
panic(err)
}
s := string(b)
// Check whether s contains substring text
if strings.Contains(s, word) == true {
fmt.Println("this is a word ", word)
} else {
fmt.Println("this isn't a word ", word)
}
strings.Contains()
reports if a substrings is contained within a string. It doesn't check for word boundaries, so the behaviour you're seeing is expected.
What you want instead is to recognize every word as a word. There is already the strings.Fields()
function to split text by whitespace. A simple implementation might look like:
func main() {
source := `
hello
world
kingdom
foo
`
check := "gdo"
words := strings.Fields(strings.ToLower(source))
for _, w := range words {
if w == check {
fmt.Println("found", check)
break
}
}
}
I used strings.Fields()
because I don't know the contents of your words.txt
file. You can also use strings.Split()
if you know the separator is always a single newline or single space.
This will be slow if you're doing a lot of lookups, since it's looping over the words
array for every lookup. A faster method would be to store it in a map:
func main() {
source := `
hello
world
kingdom
foo
`
check := "gdo"
words := make(map[string]struct{})
for _, w := range strings.Fields(strings.ToLower(source)) {
words[w] = struct{}{}
}
_, ok := words[check]
if ok {
fmt.Println("found", check)
}
}
If you're doing just a single lookup the first method will be faster (as this map method will always need to loop the full array at least once to build the map).
I used the somewhat strange looking empty struct for the map value as this doesn't allocate any memory (words[w] = true
would).
Here is a simple solution. You can convert s into a string array. Then loop through the array to check if it contains the word.
var word = strings.ToLower(string(a))
// read the whole file at once
b, err := ioutil.ReadFile("words.txt")
if err != nil {
panic(err)
}
s := string(b)
// convert the string into a string array (words)
content := strings.Split(s, " ")
contains := false
for i:=0 ; i<len(content) ; i++ {
if content[i] == word {
contains = true
break
}
}
// Check whether s contains substring text
if contains {
fmt.Println("this is a word ", word)
} else {
fmt.Println("this isn't a word ", word)
}
No need to complicate things. Have a great day :)