Home > Software design >  Strange performing of map data type
Strange performing of map data type

Time:10-17

I am trying to add a bunch of values in a map data type and after that trying to print it out. But it is performing strangely. When I am directly calling the map with the key it is giving me the correct output but not giving me any output when I am storing the key in a variable and then calling it. I am not been able to figure it out what is happening and why am I getting this kind of output. Can Somebody help me with the same.

package main

import (
"bufio"
"fmt"
"os"
)
func main(){
type Authentication struct {
    password string
}
var authentication = map[string]Authentication{}

var user1 Authentication
user1.password = "abc"
authentication["def"] = user1

reader := bufio.NewReader(os.Stdin)
usid := readString(reader)

fmt.Println(authentication)
fmt.Println(authentication[usid])
fmt.Println(authentication["def"])
}
// Reading input functions
func readString(reader *bufio.Reader) string {
s, _ := reader.ReadString('\n')
for i := 0; i < len(s); i   {
    if s[i] == '\n' {
        return s[:i]
    }
}
return s
}

Input:

def   

Output:

map[def:{abc}]

{abc}

CodePudding user response:

You're trying to do the same thing twice in readString. But all you have to do is to cut it by one byte.

func readString(reader *bufio.Reader) string {
    s, _ := reader.ReadString('\n')

    return s[:len(s)-1]
}

CodePudding user response:

There can always be a better way of reading string, but I see your code works too. I ran it in my local and it gives the expected output: enter image description here

From your description, I presume you are using go playground or any such platform. If that is so, the thing is, go playground doesn't take standard input, and your code has reader on os.Stdin. When I copy your code to playground and add the following line to check,

fmt.Printf("Length of usid: %d\nusid: %q\n", len(usid), usid)

I see the following output:

Length of usid: 0
usid: ""

Conclusion: There is no issue with variables, map or code, but just the stdin.

CodePudding user response:

The program in the question does not work when \r\n is used as the line terminator in stdin. The program removes the trailing \n from the line, but not the \r.

Fix by using bufio.Scanner instead of bufio.Reader to read lines from the input. The bufio.Scanner type removes line terminators.

func main() {
    type Authentication struct {
        password string
    }
    var authentication = map[string]Authentication{}

    var user1 Authentication
    user1.password = "abc"
    authentication["def"] = user1

    scanner := bufio.NewScanner(os.Stdin)
    if !scanner.Scan() {
        log.Fatal(scanner.Err())
    }
    usid := scanner.Text()

    fmt.Println(authentication)
    fmt.Println(authentication[usid])
    fmt.Println(authentication["def"])
}
  • Related