Правильно на вводе, но паника на выходе в golang

Пытаясь написать немного go, я хотел бы создать что-то вроде функции cat в Golang:

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: ошибка выполнения: индекс вне допустимого диапазона

горутина 1 [работает]: panic(0x4b1840, 0xc42000a0e0) /usr/lib/go/src/runtime/panic.go:500 +0x1a1 main.main() /home/user/git/go-experimentations/gocat/gocat. go:23 +0x4ba статус выхода 2


person aurelien    schedule 27.12.2016    source источник
comment
os.Args содержит то, что было передано вашей программе в командной строке. Предполагается, что вы намереваетесь открыть файл, имя которого было введено пользователем в интерактивном режиме и попало в переменную с именем input. Почему, черт возьми, вы не пытаетесь использовать его в качестве имени файла для ввода?   -  person kostix    schedule 27.12.2016
comment
запросить пользователя   -  person aurelien    schedule 27.12.2016
comment
Э... что? Я не могу понять это.   -  person kostix    schedule 27.12.2016
comment
о, извини, я только что понял, что ты имеешь в виду -_-'   -  person aurelien    schedule 27.12.2016


Ответы (3)


Вы используете =, а не := Итак, вот откуда ваша ошибка.

person Uncle Bob    schedule 16.01.2018

Я предполагаю, что вы нашли несколько примеров в Интернете и не совсем понимаете, что происходит.

Из документации пакета 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))

Вам нужно привести bs, который в настоящее время []byte, к string, и вам нужно добавить %s, чтобы указать на fmt.Printf, где string(bs) должно быть помещено в строку формата.

person jmaloney    schedule 27.12.2016
comment
вывод производит ввод + вывод, но мне нужен только вывод (что, если я даю полную информацию о каталогах, но я хочу использовать ~/для пользователя, и это возвращает, что программа сломана - person aurelien; 27.12.2016
comment
Удалить ввод будет легко, просто удалите его из оператора Printf. fmt.Printf("%s", string(bs)) использование ярлыка ~ добавит немного программирования. Вы можете проверить, является ли первый символ ~, и получить переменную env $HOME, используя os.Getenv затем создайте свой путь с помощью $HOME - person jmaloney; 27.12.2016
comment
nop, которые выдают ошибку на ~/bob и ввод+вывод на вывод на /home/user/bob - person aurelien; 27.12.2016
comment
Не совсем уверен, что вы имеете в виду. В чем ошибка? Является ли файл /home/user/bob доступным для чтения? - person jmaloney; 27.12.2016
comment
cat ~/bob читается нормально, но не запускает gocat.go после запроса ~/bob - person aurelien; 27.12.2016

не os.Open(os.Args[1]), Args[1] вне диапазона. вы должны открыть файл, который вы вводите, следующим образом:

f, err := os.Open(input)
person jfly    schedule 27.12.2016
comment
с этим по запросу я получил: - person aurelien; 27.12.2016
comment
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 - person aurelien; 27.12.2016
comment
звучит лучше, но вывод не просто хороший .. теперь получите: go run gocat2.go Какой файл вы хотите прочитать?: ~/bob ~/bob2016/12/27 16:23.10 моя программа не работает, статус выхода 1 - person aurelien; 27.12.2016
comment
и если я укажу /home/user/, он выдаст вывод, например: /home/user/bobinput%!(EXTRA []uint8=[104 109 109 32 104 109 109 10]) - person aurelien; 27.12.2016
comment
@aurelien просто введите имя файла и используйте fmt.Printf("input %s", bs) для печати текстового файла. - person jfly; 27.12.2016
comment
этот продукт: ~/bob2016/12/27 16:38:08 моя программа не работает, статус выхода 1 - person aurelien; 27.12.2016
comment
и с /home/user/bob только с %s и/или с вводом %s он производит вывод не только с ответом, но и с вводом и выводом - person aurelien; 27.12.2016
comment
Это было то + дело в том, что слишком много строки с выводом на печать ввода на fmt.Print(input), которого не должно быть и выдавать строку ввода + на вывод - person aurelien; 28.12.2016