Search code examples
filegoslicestring-comparison

Putting text file into slice then compare


I am writing a program where I take usernames line by line in a .txt file and verify that the username is in it. I have then created a slice and converted the file into a string and appended it to the string slice. I'm now trying to loop over the slice using a for loop to find a username that's in the file and compare it to another string variable that contains the username. I want to check for and see if it is in the slice. What is the best way to do this? I've tried comparing the elements in range using a for loop of the slice with the variable with the username I want to check but it's not working. So in other words I want to find out the best way to take a txt file that contains a list of just usernames added to it from top to bottom, have my program read (loop over) from that text file, and compare it with a predetermined item (username) in a string variable with what's in the text file and determine if it matches or not.

Username (string variable) == Username (in text file)

*Also the username variable will be based on what a user of the program enters into it. So I'm trying to ultimately check if when a user enters their username the program will verify if it's in the file or not. Thanks.

Code example I've tried:

var readSystemCtl []string
readSystemCtl = append(readSystemCtl, string(file))
for _, username := range of readSystemCtl {
    if username == input {
        //Continue program if true 
        break
    }else {
        //Do something else
    }
}

Note: string(file) is the text file i'm trying to read from; and input, is the string variable that the user will had input for their username that is predetermined earlier in the program.


Solution

  • As a Go programmer, I quickly translated your overall application requirements into a Go program. I then compared it to your code. I don't understand why you use a linear search of a Go slice. Why not use a random access to a Go map?


    Before comparing user names for equality, trim white space (strings.TrimSpace) and, for case insensitivity, convert to lowercase (strings.ToLower).


    users.go

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "os"
        "strings"
    )
    
    func loadUsers(r io.Reader) (map[string]bool, error) {
        users := make(map[string]bool)
        scnr := bufio.NewScanner(r)
        for scnr.Scan() {
            user := strings.TrimSpace(scnr.Text())
            if len(user) > 0 {
                user = strings.ToLower(user)
                users[user] = true
            }
        }
        if err := scnr.Err(); err != nil {
            return nil, err
        }
        return users, nil
    }
    
    func loadUsersFile(name string) (map[string]bool, error) {
        f, err := os.Open(name)
        if err != nil {
            return nil, err
        }
        defer f.Close()
        users, err := loadUsers(f)
        if err != nil {
            return nil, err
        }
        return users, nil
    }
    
    func isUser(users map[string]bool, user string) bool {
        user = strings.TrimSpace(user)
        user = strings.ToLower(user)
        return users[user]
    }
    
    func main() {
        users, err := loadUsersFile("users.txt")
        if err != nil {
            fmt.Fprintln(os.Stderr, err)
            os.Exit(1)
        }
    
        scnr := bufio.NewScanner(os.Stdin)
        for scnr.Scan() {
            user := scnr.Text()
            fmt.Print("User: ", user)
            if isUser(users, user) {
                fmt.Println(" found")
            } else {
                fmt.Println(" not found")
            }
        }
        if err := scnr.Err(); err != nil {
            fmt.Fprintln(os.Stderr, err)
            os.Exit(1)
        }
    }
    

    $ cat users.txt
    username1
    Username2
    UserName3
    $ go build users.go
    $ ./users
    User Name X
    User: User Name X not found
    username3
    User: username3 found
    $