I'm trying to make a basic adding calculator in Go (complete noob here), but every time I'm getting an output of 0.
This is the code:
package main
import (
"fmt"
"strconv"
//"flag"
"bufio"
"os"
)
func main(){
reader := bufio.NewReader(os.Stdin)
fmt.Print("What's the first number you want to add?: ")
firstnumber, _ := reader.ReadString('\n')
fmt.Print("What's the second number you want to add?: ")
secondnumber, _ := reader.ReadString('\n')
ifirstnumber, _ := strconv.Atoi(firstnumber)
isecondnumber, _ := strconv.Atoi(secondnumber)
total := ifirstnumber + isecondnumber
fmt.Println(total)
}
bufio.Reader.ReadString() returns data up until and including the separator. So your string actually ends up being "172312\n". strconv.Atoi() doesn't like that and returns 0. It actually returns an error but you're ignoring it with _.
You can see what happens with this example:
package main
import (
"fmt"
"strconv"
)
func main(){
ifirstnumber, err := strconv.Atoi("1337\n")
isecondnumber, _ := strconv.Atoi("1337")
fmt.Println(err)
fmt.Println(ifirstnumber, isecondnumber)
}
You can trim the newlines with strings.Trim(number, "\n").
Related
I read a line with bufio.NewReader(os.Stdin), then I read a string with fmt.Scanf.
package main
import (
"fmt"
"bufio"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
var str string
inp, _ := reader.ReadString('\n')
fmt.Scanf("%s", &str)
fmt.Println(inp)
fmt.Printf(str)
}
Input:
This is a sentence.
John
I expect the output to be like above, but it isn't.
Output:
This is a sentence.
actually fmt.Scanf("%s", &str) doesn't work.
What is the problem? and How can I fix it?
reader.ReadString(delim) reads everything up to the delim, including the delimiter. So, it adds \n between two inputs. fmt.Printf(str) does not have \n in the end, so the second output sticks to the next thing printed to stdout.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
var str string
inp, _ := reader.ReadString('\n')
fmt.Scanf("%s", &str)
fmt.Println(inp)
fmt.Printf(str)
}
Input:
some line
John
Output:
some line
John
Below is the code that runs as you want it to.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
var str string
inp, _ := reader.ReadString('\n')
fmt.Scanf("%s", &str)
fmt.Print(inp)
fmt.Printf("%s\n", str)
}
I want to get the string length, here my code:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to send: ")
text, _ := reader.ReadString('\n')
fmt.Print(strconv.Itoa(len(text)))
}
For input: aaa
The output is 5 but should be 3.
I know I can just subtract -2 from the result but I want "cleaner" way
You need to remove whitespaces from your input:
import (
"fmt"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to send: ")
text, _ := reader.ReadString('\n')
newText := strings.TrimSpace(text)
fmt.Print(strconv.Itoa(len(newText)))
}
I want to read user input and use it as an argument for a command. I got this code:
package main
import (
"bufio"
"fmt"
"log"
"os"
"os/exec"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter img path: ")
imgPath, _ := reader.ReadString('\n')
args := []string{imgPath, "stdout", "-l spa+eng"}
out, err := exec.Command("tesseract", args...).Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}
But when I execute it it outputs an error saying exit status 1.
If instead of using the variable imgPath as an argument I write some text directly into the array it works like a charm.
The following code returns a line with the delimiter (I work on Windows and its EOL is '\r\n'), something that wasn't shown when I printed it on the console.
reader := bufio.NewReader(os.Stdin)
imgPath, _ := reader.ReadString('\n')
In my case it ended up working after I trimmed '\r\n' from the input:
package main
import (
"bufio"
"fmt"
"log"
"os"
"os/exec"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter img path: ")
imgPath, _ := reader.ReadString('\n')
imgPath= strings.TrimRight(line, "\r\n")
args := []string{imgPath, "stdout", "-l spa+eng"}
out, err := exec.Command("tesseract", args...).Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}
pi#raspberrypi:~/Desktop/go $ go run shell1.go
As result i am getting:
pi#raspberrypi:~/Desktop/go $ go run shell1.go
# command-line-arguments
./shell1.go:29: undefined: n
./shell1.go:29: cannot use b (type []byte) as type string in argument to strconv.ParseFloat
./shell1.go:32: undefined: n
Go file (shell1.go) code is:
package main
import (
// "net/http"
// "github.com/julienschmidt/httprouter"
"fmt"
"log"
"os/exec"
"strconv"
"time"
//"bytes"
//"encoding/binary"
)
import _ "github.com/go-sql-driver/mysql"
import _ "database/sql"
func main() {
for {
time.Sleep(10 * time.Millisecond)
cmd := exec.Command("gpio.bash")
b, err := cmd.Output()
if err != nil {
log.Fatal(err)
}
n, _ = strconv.ParseFloat(b, 10)
fmt.Println(string(b))
break
}
fmt.Println("Button pressed!!! ", n)
}
Content of (gpio.bash) file is just one command to read gpio
#!/bin/bash
gpio read 29
You are working with a command here, which can of course execute just about anything.
The function is purposely generic, as the true return type varies depending on what you executed. Thus, when you call the output method, you are given a slice of bytes (very generic!). Here is its signature:
func (c *Cmd) Output() ([]byte, error)
If you know that the bytes will always be a string, then you simply have to do a type conversion to a string:
n, _ := strconv.ParseFloat(string(b), 10)
Is there a way to scan a big.Int directly from the standard input in Go? Right now I'm doing this:
package main
import (
"fmt"
"math/big"
)
func main() {
w := new(big.Int)
var s string
fmt.Scan(&s)
fmt.Sscan(s, w)
fmt.Println(w)
}
I also could have used .SetString. But, is there a way to Scan the big.Int directly from the standard input without scanning a string or an integer first?
For example,
package main
import (
"fmt"
"math/big"
)
func main() {
w := new(big.Int)
n, err := fmt.Scan(w)
fmt.Println(n, err)
fmt.Println(w.String())
}
Input (stdin):
295147905179352825857
Output (stdout):
1 <nil>
295147905179352825857
As far as I know - no, there's no other way. In fact, what you've got is the default example they have for scanning big.Int in the documentation.
package main
import (
"fmt"
"log"
"math/big"
)
func main() {
// The Scan function is rarely used directly;
// the fmt package recognizes it as an implementation of fmt.Scanner.
i := new(big.Int)
_, err := fmt.Sscan("18446744073709551617", i)
if err != nil {
log.Println("error scanning value:", err)
} else {
fmt.Println(i)
}
}
You can see the relevant section here - http://golang.org/pkg/math/big/#Int.Scan