如何从控制台线读取输入?

Dan*_*nte 251 go

我想从命令行读取输入,但是在我被提示输入之前,我的尝试已经结束,程序退出.我在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)
}
Run Code Online (Sandbox Code Playgroud)

Lin*_*ope 267

我不确定该块有什么问题

reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Println(text)
Run Code Online (Sandbox Code Playgroud)

因为它适用于我的机器.但是,对于下一个块,您需要一个指向您要为其分配输入的变量的指针.尝试更换fmt.Scanln(text2)fmt.Scanln(&text2).不要使用Sscanln,因为它解析已经在内存中的字符串而不是stdin.如果您想要做类似于您尝试的操作,请将其替换为fmt.Scanf("%s", &ln)

如果这仍然不起作用,你的罪魁祸首可能是一些奇怪的系统设置或一个错误的IDE.

  • @ 425nesp是的,那是分隔符,它是一个单字节.http://golang.org/pkg/bufio/#Reader.ReadString (8认同)
  • 那些应该是单引号吗?`ReadString('\ n')`或`ReadString(“ \ n”)`? (2认同)
  • 好的答案,但是当我尝试使用退格键等失败 (2认同)
  • 对于Golang来说,通过阅读器rd读取文件中的一行到变量s如此多,如果if s,_ = rd.ReadString('\ n'); true {s = strings.Trim(s,“ \ n”)}` (2认同)
  • 只是分享一个有趣的事情(我是Golang初学者):\ n必须在单引号内(不要尝试使用双引号)。否则,它将重现此内容:`不能将“ \ n”(类型字符串)用作reader.ReadString的参数中的类型字节。 (2认同)
  • 显然,如果你这样做,“text”将会有一个尾随的“↵”。 (2认同)

Hel*_*ang 116

你也可以尝试:

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

if scanner.Err() != nil {
    // handle error.
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好,简洁的方式来读取标准输入! (10认同)
  • 如果您只想输入一行,则可以删除"for {}". (6认同)
  • 您将收到此错误**bufio.Scanner:令牌太长**如果您的输入大于64*1024字节.另外不要忘记在for循环下添加`fmt.Println(scanner.Err())`. (5认同)
  • 如果有for {}循环,如何在进入时从循环中出来?是否存在使循环停止的特殊字符?- 谢谢 (2认同)
  • @Madhan Scanner.Scan()返回布尔值,以指示是否退出for循环。 (2认同)

Pit*_*ith 86

我认为更为标准的做法是:

package main

import "fmt"

func main() {
    fmt.Print("Enter text: ")
    var input string
    fmt.Scanln(&input)
    fmt.Print(input)
}
Run Code Online (Sandbox Code Playgroud)

看看scangodoc:http://godoc.org/fmt#Scan

扫描扫描从标准输入读取的文本,将连续的空格分隔值存储到连续的参数中.换行计为空格.

Scanln类似于Scan,但是在换行符处停止扫描,在最终项目之后必须有换行符或EOF.

  • 这似乎不喜欢输入字符串中的空格. (10认同)
  • 为此打开了一个错误:https://github.com/golang/go/issues/5703它被关闭为WorkingAsIntended.另见:http://stackoverflow.com/questions/24005899/fmt-scanln-expected-newline-error和https://groups.google.com/forum/#!topic/golang-nuts/r6Jl4D9Juw0似乎很多人们对此有疑问.需要更改文档?此外,从最后一个链接:"Scan和Scanln用于解析和类似的东西,所以只是从stdin获取单行文本将失败目的." (6认同)
  • @HairyChris是的,这很奇怪.在文档中它说`停止在换行符处扫描,在最终项目之后必须有换行符或EOF`所以不确定为什么空间"打破"它......我猜这是一个bug (3认同)
  • 使用`fmt.Scanln`和`fmt.Scan`与当前的2016 go版本(go版本为1.6.2 linux/amd64)时,空格仍然存在同样的问题. (3认同)

Nar*_*ula 19

始终尝试使用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)
}
Run Code Online (Sandbox Code Playgroud)

如果您不想以编程方式收集输入,只需添加这些行

   scanner := bufio.NewScanner(os.Stdin)
   scanner.Scan()
   text := scanner.Text()
   fmt.Println(text)
Run Code Online (Sandbox Code Playgroud)

上述程序的输出将是:

Enter Text: Bob
Bob
Enter Text: Alice
Alice
Enter Text:
[Bob Alice]
Run Code Online (Sandbox Code Playgroud)

上面的程序收集用户输入并将它们保存到数组中.我们也可以用特殊的角色打破这种流动.Scanner为高级用法提供API,例如使用自定义函数进行拆分等,扫描不同类型的I/O流(Stdin,String)等.

  • @维克多,是的。如果您通读官方 bufio 文档,“Text 将调用 Scan 生成的最新令牌作为新分配的保存其字节的字符串返回。” 这完全回答了你的问题。https://golang.org/pkg/bufio/#Scanner.Text (2认同)

Chi*_*xus 10

在循环中读取多个输入的另一种方法是可以处理带空格的输入:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

  • 您可能只需要在内部的“ q”检查中使用一个break并将其包装在无限循环中即可。好的答案! (2认同)
  • 看起来您现在也可以在for循环中摆脱条件。 (2认同)

Shi*_*hra 8

我参加聚会迟到了。但是一个班轮怎么样:

data, err := ioutil.ReadAll(os.Stdin)
Run Code Online (Sandbox Code Playgroud)

完成后按 ctrl+d 。

  • 是的,就可以了 - 让我想起用 `mail` 写电子邮件。 (3认同)
  • 按 ctrl+d 即 eot。 (2认同)

Nit*_*dav 7

也可以这样做:

package main
import "fmt"

func main(){
    var myname string
    fmt.Scanf("%s", &myname)
    fmt.Println("Hello", myname)
}
Run Code Online (Sandbox Code Playgroud)


Roh*_*wiz 5

干净地读入几个提示值:

// 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))
Run Code Online (Sandbox Code Playgroud)

这是一个运行:

Enter text: Jim
Enter More text: Susie
Text1: "Jim", Text2: "Susie"
Run Code Online (Sandbox Code Playgroud)

  • 这也是一个很好的方法,因为 strings.TrimSpace 删除了 '\n'。而且我相信 reader.ReadString('\n') 也是跨平台的。 (2认同)

小智 5

试试这个代码:

var input string
func main() {
    fmt.Print("Enter Your Name=")
    fmt.Scanf("%s", &input)
    fmt.Println("Hello " + input)
}
Run Code Online (Sandbox Code Playgroud)

  • 似乎`Scanf()` 不接受字符串中的空格 (5认同)

小智 5

您需要提供指向要扫描的变量的指针,如下所示:

fmt.scan(&text2)
Run Code Online (Sandbox Code Playgroud)