Why is second scanf being skipped over? - go

I decided to take a look at Go and I am currently stuck on something. In this program, I am asking the user to choose option 1 or 2. If option 1 is chosen, I want the ReadAppList function to ask the user for a last name.
It seems as if the second scanf is being skipped over and not allowing the user to enter a last name. Is it only reading the first user input?
package main
import (
"fmt"
)
// Main function that runs on startup
func main() {
fmt.Println("\n1. Search Last Name ")
fmt.Println("\n2. Exit ")
fmt.Println("\nPick an option: ")
var userAnswer int
fmt.Scanf("%d", &userAnswer)
if userAnswer == 1 {
ReadAppsList()
} else if userAnswer == 2 {
fmt.Println("\nGoodbye.")
} else {
fmt.Println("\nThat is not a valid choice.")
}
}
func ReadAppsList() {
fmt.Println("\nType your LastName of the person you want to look up: ")
var lastName string
fmt.Scanf("%s", &lastName)
fmt.Sprintf("You typed %s", lastName)
}

That's because extra newline not being consumed by first scanf.
Change your scanf to this fmt.Scanf("%d\n", &userAnswer).

In your ReadAppsList you have:
fmt.Sprintf("You typed %s", lastName)
The problem is that Sprintf returns a string without writing to the screen. Change that to Printf and it'll print the lastname.
The Scanf for the last name is happening as you'd expect.

Related

Print User input to physical printer in Golang

I'm new here in Golang world for a week.. I've been research and still don't know how to print from user input to physical printer, from USB to printer.
For example I have done with code, just need add other function to print..
package main
import "fmt"
func main() {
fmt.Println("First name: ")
var name1 string
fmt.Scanln(&name1)
)
fmt.Println("Last name: ")
var name2 string
fmt.Scanln(&name2)
fmt.Print("My full name is: ")
fmt.Print(name1 + " " + name2)
}
func print(){
//need function to print directly from USB to pyhsical printer..
//print from func main() as text, any format
}
I have no idea to create print func in golang from user input..
If successful, then after func main() println, then immediately send the command to print to my printer.. just using terminal, I don't need the GUI.
Thank you for helping me:')

GoLang fmt.Scan type error skip next fmt.Scan

Am a beginner of GoLang here is a sample code from a tutorial.
func main() {
for {
var name string
var email string
var userTickets uint
// ask user for info
fmt.Println("Input your Name please")
fmt.Scan(&name)
fmt.Println("Input your Email please")
fmt.Scan(&email)
// ask user for number of tickets
fmt.Println("Input number of ticket")
if _, err := fmt.Scanln(&userTickets); err != nil {
fmt.Println(err)
}
}
}
Here is an interesting thing I found:
if I entered "-1" in "Input number of ticket". It will throw an error since userTickets is uint. With that err it will also put an "enter/next line" for "Input your Name please" in the next loop.
The result would look like this
Input your Name please
Test
Input your Email please
Test
Input number of tickect
-1
expected integer
Input your Name please <= this input is skipped
Input your Email please
So just wondering why this heppened? How can I resolve that (without changing type from uint to int)?
So just wondering why this heppened?
Because -1 cannot be stored in an uint.
How can I resolve that (without changing type from uint to int)?
You cannot.
(The right thing to do is not to use fmt.Scan but to always read whole lines into a string and parse the string.)

Why does fmt.Scan() behave in a weird way?

I'm trying to validate the user input. If the user inputs an integer number it works like expected. However, if the user inputs a non-integer string, the variable userTickets gets assigned value 0, but prints Try again! It must be more than zero: many times. To be exact, it prints len(input) times and I don't understand why.
Also tried achieving desired result using fmt.Scanf("%d", &usertickets) but got an identical result.
Why does it behave this way and how can I write a workaround for it?
package main
import "fmt"
func main() {
var remainingTickets uint = 50
var userTickets uint
fmt.Print("Enter the number of tickets you want to purchase: ")
fmt.Scan(&userTickets)
for userTickets > remainingTickets {
fmt.Printf("We only have %v tickets available!\n", remainingTickets)
fmt.Print("Try again! Enter the number of tickets: ")
fmt.Scan(&userTickets)
}
for userTickets == 0 {
fmt.Print("Try again! It must be more than zero: ")
fmt.Scan(&userTickets)
}
fmt.Printf("Remaining tickets: %v\n", remainingTickets-userTickets)
}
Scan is able to determine that the input isn't numeric without reading the entire contents of stdin. This is why you validation logic loops for len(input) when non-numeric. While you can use a Scanner as well (and people do recommend that approach), below is an approach similar to yours. Note that all validation checking is done within a single "for" loop as well:
package main
import (
"fmt"
"strconv"
)
func main() {
var remainingTickets uint64 = 50
fmt.Print("Enter the number of tickets you want to purchase: ")
for {
var userTickets string
fmt.Scanln(&userTickets)
// parse to make sure we get a positive (unsigned) integer
u64, err := strconv.ParseUint(userTickets,10,64)
// make sure it's a postive integer and not equal to zero
if err != nil || u64==0{
fmt.Print("Try again! You must enter a number greater than zero: ")
continue
}
// check to make sure we have enough tickets left
if u64 > remainingTickets {
fmt.Printf("We only have %v tickets available!\n", remainingTickets)
fmt.Print("Try again! Enter the number of tickets: ")
continue
}
// update remaining tickets
remainingTickets -= u64
break
}
fmt.Printf("Remaining tickets: %d\n", remainingTickets)
}

reading same input with bufio and scanf has different results

I was trying to write a simple program that reads some answers from the terminal from the user to some questions.For instance the queries are:
5+5
1+2
8+3
and the user should give the answer.My problem it that when I user bufio.ReadString and the compare the input with the real answer it doesn't work properly,how ever when I use scanf everything is fine.here is my code:
//scanner := bufio.NewReader(os.Stdin)
var correctAnswers int8 = 0
for _, pro := range problems {
fmt.Println(pro.question)
//answer,_ := scanner.ReadString('\n')
var idk string
fmt.Scanf("%s\n", &idk)
//print(answer)
println(pro.answer)
if idk == pro.answer {
fmt.Println("Correct :)")
correctAnswers++
} else {
fmt.Println("Sorry!")
}
}
fmt.Printf("You answered %d out of %d problems correctly \n", correctAnswers, len(problems))
as you can see I commented out bufio. The intersting thing is that when I print the answer that the user gave me it bufio.ReadString correctly got the input from terminal but in the if clause it doesn't work!
bufio.Reader.ReadString:
ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter.
The value returned from ReadString includes the \n on the end.

Variable capturing in string literal in Go?

In Ruby, I could directly capture variables in string literals like in bash.
SRCDIR = "aaa"
DSTDIR = "bbb"
puts "SRCDIR = #{SRCDIR}"
puts "DSTDIR = #{DSTDIR}"
This is a simple and tiny feature, but very nice to make it feel like a shell script. If I have to write a complex shell script this helps a lot because this eliminates the need for substitution, concatenation and format expression.
Does Go have something like this? If it does, how to use it?
Not without a formatting string; the usual way to do this is with fmt.Printf or fmt.Sprintf:
srcdir := "aaa"
dstdir := "bbb"
// separated out Sprintf and Println for clarity
fmt.Println(fmt.Sprintf("SRCDIR = %s", srcdir))
fmt.Println(fmt.Sprintf("DSTDIR = %s", dstdir))
// could be shortened if you're just printing them
fmt.Printf("SRCDIR = %s\n", srcdir)
fmt.Printf("DSTDIR = %s\n", dstdir)
You have to concat with the + operator as in JS
main.go
package main
import "fmt"
func main() {
movieQuote := `"What's the most you ever lost on a coin toss?"`
statement := `Back-ticks allow double quotes, ` + movieQuote + `, and single quote apostrophe's`
fmt.Println("movieQuote: ", movieQuote)
fmt.Println("statement: ", statement)
}
Run
go run main.go
Output:
movieQuote: "What's the most you ever lost on a coin toss?"
statement: Back-ticks allow double quotes, "What's the most you ever lost on a coin toss?", and single quote apostrophe's
What Wes said. I should add that if you're using custom types, you might define a method which has the signature String() string on them (to essentially make them satisfy the fmt.Stringer interface) and then pass instances of these types directly to functions of the fmt package which expect a string, such as fmt.Println(). A simple introduction to this might be found in "Effective Go".
GQL Queries
package main
import (
"github.com/gookit/color"
)
const (
offerInfo string = `{
id
name
description
logoURL
opt_ins {
id
name
description
}
}`
)
func QueryAllOffers() string {
return `{ offer ` + offerInfo + `}`
}
func QueryOfferByID(id string) string {
return `{
offer (id: "` + string(id) + `")` + offerInfo + ` }`
}
func main() {
queryAllOffers := QueryAllOffers()
color.Cyan.Println(queryAllOffers)
offerID := "0001"
queryOfferByID := QueryOfferByID(offerID)
color.Blue.Println(queryOfferByID)
}
Output: queryAllOffers
{
offer {
id
name
description
logoURL
opt_ins {
id
name
description
}
}
}
Output: queryOfferById
{
offer(id: "0001") {
id
name
description
logoURL
opt_ins {
id
name
description
}
}
}

Resources