我想从命令行读取标准输入,但是在提示我输入之前,我的尝试以结束程序退出而告终。 我正在寻找C#中的Console.ReadLine()等效项。
这是我目前拥有的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package main import ( "bufio" "fmt" "os" ) func main() { reader := bufio.NewReader(os.Stdin) fmt.Print("Enter text:") text, _ := reader.ReadString(' ') fmt.Println(text) fmt.Println("Enter text:") text2 :="" fmt.Scanln(text2) fmt.Println(text2) ln :="" fmt.Sscanln("%v", ln) fmt.Println(ln) } |
- 此代码看起来正确。 出于好奇,您正在操场上运行此游戏吗? 由于联网原因,Go Playground不允许标准输入。
- @Jsor Im在本地运行。
- 没关系,这似乎是一个微妙的问题,您需要一个指针(请参阅我的回答)。 虽然我不确定bufio.NewReader方法的问题是什么,因为它对我有用。
- 从GO的初始stdin读取的可能重复项?
-
不要将任何读取器(例如
bufio.NewReader(os.Stdin) )的bufio 缓冲与从下划线读取器(例如fmt.Scanln(x) 直接从os.Stdin 直接读取)的直接读取混合使用。 缓冲可以任意向前读取。 (在这种特定情况下,后者应为fmt.Fscanln(reader,x) 以便从同一缓冲区读取)。 -
我没有得到
fmt.Sscanln 的效果,运行后它变为"%v"
我不确定块有什么问题
1 2 3 4 5 | reader := bufio.NewReader(os.Stdin) fmt.Print("Enter text:") text, _ := reader.ReadString(' ') fmt.Println(text) |
因为它可以在我的机器上使用。但是,对于下一个块,您需要一个指针,该指针指向要将输入分配给它们的变量。尝试用
如果仍然无法解决问题,您的罪魁祸首可能是某些奇怪的系统设置或错误的IDE。
- 你是对的!我在Windows上使用GoSublime,它在那里不起作用,但是切换到字符串指针后在命令提示符下起作用。奇怪的是,bufio.NewReader(os.Stdin)之前都没有在命令提示符下工作。
-
那些应该是单引号吗?
ReadString( 或
)ReadString(" ?
") - @ 425nesp是的,多数民众赞成在分隔符,这是一个字节。 golang.org/pkg/bufio/#Reader.ReadString
- 好的答案,但是当我尝试使用退格键等失败
-
对于Golang来说,通过读取器
rd 从文件读取行到变量s 为if s,_ = rd.ReadString( 是如此多
); true { s = strings.Trim(s,"
") } -
只是分享一件有趣的事情(我是Golang初学者): n必须在单引号内(不要尝试使用双引号)。否则,它将重现此内容:
cannot use"
" (type string) as type byte in argument to reader.ReadString -
如果执行此操作,显然
text 将具有结尾的? 。
您也可以尝试:
1 2 3 4 5 6 7 8 | scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { fmt.Println(scanner.Text()) } if scanner.Err() != nil { // handle error. } |
- 这是阅读stdin的一种很好,简洁的方法!
- 如果您只想输入一个一行,则可以删除" for {}"。
- 如果有for {}循环,如何在进入时从循环中出来?是否存在使循环停止的特殊字符? - 谢谢
- @Madhan Scanner.Scan()返回布尔值,以指示是否退出for循环。
-
如果输入大于64 * 1024字节,则会收到此错误bufio.Scanner:令牌太长。同样不要忘记在for循环下面添加
fmt.Println(scanner.Err()) 。 - 如果我输入" abc n ^ D",期望的字符串是" abc n",但返回" abc",该怎么办。
- @YuvarajLoganathan我们可以将大小(64 * 1024字节)增加到无限吗?
- 我们不能增加限制。它被硬编码到go运行时中。
我认为更标准的方法是:
1 2 3 4 5 6 7 8 9 10 | package main import"fmt" func main() { fmt.Print("Enter text:") var input string fmt.Scanln(&input) fmt.Print(input) } |
看看
Scan scans text read from standard input, storing successive space-separated values into successive arguments. Newlines count as space.
Scanln is similar to Scan, but stops scanning at a newline and after the final item there must be a newline or EOF.
- 这似乎不喜欢输入字符串中的空格。
-
@HairyChris是的,这很奇怪。在文档中它表示
stops scanning at a newline and after the final item there must be a newline or EOF ,所以不确定为什么空间会"破坏"它...我想这是一个错误 - 为此打开了一个错误:github.com/golang/go/issues/5703它已作为WorkingAsIntended关闭。另请参阅:stackoverflow.com/questions/24005899/和groups.google.com/forum/#!topic/golang-nuts/r6Jl4D9Juw0似乎很多人对此都有疑问。需要更改文档吗?同样,从最后一个链接开始:" Scan和Scanln用于解析之类的东西,因此仅从stdin中获取一行文本就无法达到目的。"
- 对我来说,fmt.Scan的任何类似功能都让它感到困惑,在bufio.NewReader这样的空间中无法很好地发挥作用。
-
在当前的2016 go版本(go版本go1.6.2 linux / amd64)中使用
fmt.Scanln 和fmt.Scan 时,仍然存在空格问题。 -
空格行不适用于
fmt.Scanln()
始终尝试使用bufio.NewScanner从控制台收集输入。正如其他人提到的那样,有多种方法可以完成这项工作,但Scanner最初是打算完成这项工作的。 Dave Cheney解释了为什么应使用Scanner而不是bufio.Reader的ReadLine。
这是您的问题的代码片段答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 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) } |
如果您不想以编程方式收集输入,只需添加以下行
1 2 3 4 | scanner := bufio.NewScanner(os.Stdin) scanner.Scan() text := scanner.Text() fmt.Println(text) |
上面程序的输出将是:
1 2 3 4 5 6 | Enter Text: Bob Bob Enter Text: Alice Alice Enter Text: [Bob Alice] |
上面的程序收集用户输入并将其保存到数组中。我们还可以使用特殊字符来中断该流程。扫描仪提供API以供高级使用,例如使用自定义函数进行拆分等,扫描不同类型的I / O流(Stdin,String)等。
在循环中读取多个输入的另一种方法可以处理带空格的输入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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) } } } |
输出:
1 2 3 4 5 | 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 |
- 您可能只需要在内部的" q"检查中使用一个break并将其包装在无限循环中即可。好的答案!
- 看起来您现在也可以在for循环中摆脱条件。
我迟到了。但是一个班轮怎么样:
1 | data, err := ioutil.ReadAll(os.Stdin) |
-
因为
os.Stdin 不会结束,所以无法全部阅读。您可能正在等待一段时间... - 按ctrl + d,即eot。
-
是的,那就做到了-让我想起用
mail 编写电子邮件。 - 或任何接受stdin的Linux命令。
试试这个代码:
1 2 3 4 5 6 | var input string func main() { fmt.Print("Enter Your Name=") fmt.Scanf("%s",&input) fmt.Println("Hello"+input) } |
-
似乎
Scanf() 不接受字符串中的空格 - 带有空格的行不适用于fmt.Scanln()
也可以这样:
1 2 3 4 5 6 7 8 | package main import"fmt" func main(){ var myname string fmt.Scanf("%s", &myname) fmt.Println("Hello", myname) } |
干净地读取几个提示值:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // 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(' ') fmt.Print("Enter More text:") text2, _ := reader.ReadString(' ') // Trim whitespace and print fmt.Printf("Text1: "%s", Text2: "%s" ", strings.TrimSpace(text), strings.TrimSpace(text2)) |
运行:
1 2 3 | Enter text: Jim Enter More text: Susie Text1:"Jim", Text2:"Susie" |
- 这也是一个好方法,因为strings.TrimSpace删除了 n。而且我相信reader.ReadString( n)也是跨平台的。
- 我猜想大多数情况下您想默认删除 n,这就是为什么它更好的原因bufio.NewScanner as @Naren Yellavula answer
就我而言,程序没有等待,因为我正在使用
1 2 3 4 | fmt.Print("Enter text:") var input string fmt.Scanln(&input) fmt.Print(input) |
您需要提供一个指向您要扫描的var的指针,如下所示:
1 | fmt.scan(&text2) |