在golang中输入正确但输出恐慌

Posted

技术标签:

【中文标题】在golang中输入正确但输出恐慌【英文标题】:Correct on input but panic on output in golang 【发布时间】:2016-12-27 14:57:07 【问题描述】:

试着写一点go,我想在Golang中创建一个cat函数:

package main

import (
        "fmt"
        "os"
        "io/ioutil"
        "log"
)

func main() 
        // part to ask the question and get the input
        fmt.Print("Which file would you like to read?: ")
        var input string
        fmt.Scanln(&input)
        fmt.Print(input)

        // part to give the output
        f, err := os.Open(os.Args[1]) // Open the file                                       
        if err != nil 
                log.Fatalln("my program broken")
        

        defer f.Close() // Always close things open                                          

        bs, err := ioutil.ReadAll(f)
        if err != nil 
                log.Fatalln("my program broken")
        

        // part to print the output
        fmt.Printf("input", bs) // %s convert directly in string the result                  


但我在执行时感到恐慌并且找不到更明确的信息。

我做错了什么?

如何从终端获取有关该错误的更多信息?

$ go run gocat.go 你想读哪个文件?:gocat.go gocat.gopanic:运行时错误:索引超出范围

goroutine 1 [运行]: 恐慌(0x4b1840, 0xc42000a0e0) /usr/lib/go/src/runtime/panic.go:500 +0x1a1 main.main() /home/user/git/go-experimentations/gocat/gocat.go:23 +0x4ba 退出 状态 2

【问题讨论】:

os.Args 保存在命令行中传递给程序的内容。您应该打算打开一个文件,该文件的名称由用户交互式输入,并最终出现在名为“input”的变量中。您为什么不尝试将其用作要输入的文件名? 请求用户 呃....什么?我无法理解这一点。 哦,对不起,我刚刚明白你的意思-_-' 【参考方案1】:

我想您在网上找到了一些示例,但不太了解发生了什么。

来自os 包的文档。

Args 保存命令行参数,以程序名称开头。

由于您在没有任何参数的情况下启动了程序并且os.Args 是一个切片,因此当您访问切片的边界时程序会出现混乱。 (就像试图访问任何不存在的数组的元素)

您似乎正在尝试在此处提示输入

var input string
fmt.Scanln(&input)
fmt.Print(input)

你需要做的就是替换

f, err := os.Open(os.Args[1])

与:

f, err := os.Open(input)

您最后的打印语句也不正确。

应该是:

// part to print the output
fmt.Printf("input \n %s", string(bs))

您需要将当前为[]bytebs 转换为string,并且您需要添加%s 以指示fmt.Printf 应将string(bs) 放在格式字符串中的位置

【讨论】:

输出产生输入+输出,但我只需要输出(如果我提供完整的目录信息,但我希望使用 ~/ 为用户并返回程序已损坏 删除输入很容易,只需将其从Printf 语句中删除即可。 fmt.Printf("%s", string(bs)) 使用 ~ 快捷方式将增加一点编程。您可以检查第一个字符是否为~,如果是使用os.Getenv 获取$HOME env 变量,然后使用$HOME 构造您的路径 nop 在 ~/bob 上产生错误,在 /home/user/bob 上产生输入+输出 不太清楚你的意思。错误是什么? /home/user/bob是可以读取的文件吗? cat ~/bob 读得很好,但不去运行 gocat.go 然后在请求之后 ~/bob【参考方案2】:

您使用= 而不是:= 所以这就是你的错误来自哪里。

【讨论】:

【参考方案3】:

不是os.Open(os.Args[1])Args[1] 超出范围。你应该像这样打开你输入的文件:

f, err := os.Open(input)

【讨论】:

根据我收到的请求: go run gocat2.go 你想读哪个文件?: ~/bob ~/bobpanic: 运行时错误: index out of range gorountine 1 [running]: panic(0x4...) / usr/lib/go/src/runtime/panic.go:500 +0x1a main.main() /home/user/git/go/gocat2/gocat2.go:22 +0x4ba 存在状态2 听起来更好,但输出不是很好.. 现在得到:去运行 gocat2.go 你想读哪个文件?:~/bob ~/bob2016/12/27 16:23.10 my程序损坏退出状态 1 如果我指定 /home/user/ 它会产生如下输出: /home/user/bobinput%!(EXTRA []uint8=[104 109 109 32 104 109 109 10]) @aurelien 只需输入文件名,并使用fmt.Printf("input %s", bs) 打印文本文件。

以上是关于在golang中输入正确但输出恐慌的主要内容,如果未能解决你的问题,请参考以下文章

Golang恐慌崩溃预防

Golang SWIG 示例 2:切片边界超出范围恐慌

Golang 模拟上下文恐慌

golang golang恐慌

golang - mysql 恐慌:运行时错误:无效的内存地址或 nil 指针取消引用

golang 展示恐慌,推迟和恢复结合使用的完整例子