我想从命令行读取标准输入,但我的尝试已经结束,程序在提示输入之前退出。我在 C# 中寻找相当于 Console.ReadLine() 的东西。
这是我目前拥有的:
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Println(text)
fmt.Println("Enter text: ")
text2 := ""
fmt.Scanln(text2)
fmt.Println(text2)
ln := ""
fmt.Sscanln("%v", ln)
fmt.Println(ln)
}
bufio
缓冲(例如 bufio.NewReader(os.Stdin)
)与来自下划线读取器的直接读取(例如 fmt.Scanln(x)
直接从 os.Stdin
读取)混合。缓冲可以任意向前读取。 (在这种特定情况下,后者应该是 fmt.Fscanln(reader,x)
从同一个缓冲区读取)。
fmt.Sscanln
作品,运行后它变成“%v”
我不确定该块有什么问题
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Println(text)
因为它适用于我的机器。但是,对于下一个块,您需要一个指向要分配输入的变量的指针。尝试将 fmt.Scanln(text2)
替换为 fmt.Scanln(&text2)
。不要使用 Sscanln
,因为它解析的是内存中已经存在的字符串,而不是来自标准输入的字符串。如果您想做类似您尝试做的事情,请将其替换为 fmt.Scanf("%s", &ln)
如果这仍然不起作用,那么您的罪魁祸首可能是一些奇怪的系统设置或错误的 IDE。
你也可以试试:
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if scanner.Err() != nil {
// Handle error.
}
fmt.Println(scanner.Err())
。
我认为更标准的方法是:
package main
import "fmt"
func main() {
fmt.Print("Enter text: ")
var input string
fmt.Scanln(&input)
fmt.Print(input)
}
查看 scan
godoc:http://godoc.org/fmt#Scan
Scan 扫描从标准输入读取的文本,将连续的空格分隔值存储到连续的参数中。换行符算作空格。 Scanln 类似于 Scan,但在换行处停止扫描,并且在最后一项之后必须有换行符或 EOF。
stops scanning at a newline and after the final item there must be a newline or EOF
所以不确定为什么空间会“破坏”它......我想这是一个错误
fmt.Scanln
和 fmt.Scan
时,同样的空格问题仍然存在。
始终尝试使用 bufio.NewScanner 从控制台收集输入。正如其他人所提到的,有多种方法可以完成这项工作,但 Scanner 最初是为了完成这项工作。 Dave Cheney 解释了为什么应该使用 Scanner 而不是 bufio.Reader 的 ReadLine。
https://twitter.com/davecheney/status/604837853344989184?lang=en
这是您问题的代码片段答案
package main
import (
"bufio"
"fmt"
"os"
)
/*
Three ways of taking input
1. fmt.Scanln(&input)
2. reader.ReadString()
3. scanner.Scan()
Here we recommend using bufio.NewScanner
*/
func main() {
// To create dynamic array
arr := make([]string, 0)
scanner := bufio.NewScanner(os.Stdin)
for {
fmt.Print("Enter Text: ")
// Scans a line from Stdin(Console)
scanner.Scan()
// Holds the string that scanned
text := scanner.Text()
if len(text) != 0 {
fmt.Println(text)
arr = append(arr, text)
} else {
break
}
}
// Use collected inputs
fmt.Println(arr)
}
如果您不想以编程方式收集输入,只需添加这些行
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
text := scanner.Text()
fmt.Println(text)
上述程序的输出将是:
Enter Text: Bob
Bob
Enter Text: Alice
Alice
Enter Text:
[Bob Alice]
上面的程序收集用户输入并将它们保存到一个数组中。我们也可以用一个特殊的字符打破这个流程。 Scanner 为高级用法提供 API,例如使用自定义函数进行拆分等,扫描不同类型的 I/O 流(标准 Stdin
、String
)等。
编辑:原始帖子中链接的推文不可访问。但是,可以从这个标准库文档中找到使用 Scanner 的官方参考:https://pkg.go.dev/bufio@go1.17.6#example-Scanner-Lines
scanner.Text()
之前使用 scanner.Scan()
,这是必需的,以便解析以 enter \n
结尾的标准输入的输入,对吧?
在循环中读取多个输入的另一种方法可以处理带空格的输入:
package main
import (
"fmt"
"bufio"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
var text string
for text != "q" { // break the loop if text == "q"
fmt.Print("Enter your text: ")
scanner.Scan()
text = scanner.Text()
if text != "q" {
fmt.Println("Your text was: ", text)
}
}
}
输出:
Enter your text: Hello world!
Your text was: Hello world!
Enter your text: Go is awesome!
Your text was: Go is awesome!
Enter your text: q
也可以这样做:
package main
import "fmt"
func main(){
var myname string
fmt.Scanf("%s", &myname)
fmt.Println("Hello", myname)
}
我参加晚会迟到了。但是一个班轮怎么样:
data, err := ioutil.ReadAll(os.Stdin)
完成后按 ctrl+d。
os.Stdin
没有“结束”,所以不可能全部阅读。你可能要等一段时间...
mail
写电子邮件。
io.ReadAll(os.Stdin)
清楚地读入几个提示值:
// Create a single reader which can be called multiple times
reader := bufio.NewReader(os.Stdin)
// Prompt and read
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Print("Enter More text: ")
text2, _ := reader.ReadString('\n')
// Trim whitespace and print
fmt.Printf("Text1: \"%s\", Text2: \"%s\"\n",
strings.TrimSpace(text), strings.TrimSpace(text2))
这是一个运行:
Enter text: Jim
Enter More text: Susie
Text1: "Jim", Text2: "Susie"
试试这个代码:
var input string
func main() {
fmt.Print("Enter Your Name=")
fmt.Scanf("%s", &input)
fmt.Println("Hello " + input)
}
Scanf()
不接受字符串中的空格
您需要提供指向要扫描的变量的指针,如下所示:
fmt.scan(&text2)
就我而言,程序没有等待,因为我使用 watcher
命令自动运行程序。手动运行程序 go run main.go
导致“输入文本”并最终打印到控制台。
fmt.Print("Enter text: ")
var input string
fmt.Scanln(&input)
fmt.Print(input)
Scan*
系列的限制是它们最多读取一个空格(例如空格)分隔符。
让我们做起来很简单
s:=""
b := make([]byte, 1)
for os.Stdin.Read(b) ; b[0]!='\n'; os.Stdin.Read(b) {
s+=string(b)
}
fmt.Println(s)
ReadString('\n')
还是ReadString("\n")
?rd
从文件中读取一行到变量s
作为if s,_ = rd.ReadString('\n'); true { s = strings.Trim(s, " \n") }
cannot use "\n" (type string) as type byte in argument to reader.ReadString