尝试在Golang中将键盘输入写入文件。

huangapple go评论82阅读模式
英文:

Trying to write input from keyboard into a file in Golang

问题

我正在尝试从键盘获取输入,然后将其存储在一个文本文件中,但我对如何实际操作有些困惑。

我目前的代码如下:

// 读取文件txt.txt
bs, err := ioutil.ReadFile("text.txt")
if err != nil {
panic(err)
}

// 打印内容
textInFile := string(bs)
fmt.Println(textInFile)

// 从键盘获取标准输入
var userInput string
fmt.Scanln(&userInput)

// 现在我想将输入写回到文件text.txt
// func WriteFile(filename string, data []byte, perm os.FileMode) error

inputData := make([]byte, len(userInput))

err := ioutil.WriteFile("text.txt", inputData, )

"os"和"io"包中有很多函数。我对我应该使用哪个函数感到非常困惑。

我也对WriteFile函数中的第三个参数感到困惑。在文档中它说是"perm os.FileMode"类型,但由于我是新手,对编程和Go语言都有点茫然。

有人对如何进行操作有什么提示吗?
提前感谢,
Marie

英文:

I am trying to take input from the keyboard and then store it in a text file but I am a bit confused on how to actually do it.

My current code is as follow at the moment:

// reads the file txt.txt 
bs, err := ioutil.ReadFile("text.txt")
if err != nil {
      panic(err)
}

// Prints out content
textInFile := string(bs)
fmt.Println(textInFile)

// Standard input from keyboard
var userInput string
fmt.Scanln(&userInput)

//Now I want to write input back to file text.txt
//func WriteFile(filename string, data []byte, perm os.FileMode) error

inputData := make([]byte, len(userInput))

err := ioutil.WriteFile("text.txt", inputData, )

There are so many functions in the "os" and "io" packages. I am very confused about which one I actually should use for this purpose.

I am also confused about what the third argument in the WriteFile function should be. In the documentation is says of type " perm os.FileMode" but since I am new to programming and Go I am a bit clueless.

Does anybody have any tips on how to proced?
Thanks in advance,
Marie

答案1

得分: 3

例如,

package main

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

func main() {
	fname := "text.txt"

	// 打印文本文件
	textin, err := ioutil.ReadFile(fname)
	if err == nil {
		fmt.Println(string(textin))
	}

	// 追加文本到文件
	f, err := os.OpenFile(fname, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
	if err != nil {
		panic(err)
	}
	var textout string
	fmt.Scanln(&textout)
	_, err = f.Write([]byte(textout))
	if err != nil {
		panic(err)
	}
	f.Close()

	// 打印文本文件
	textin, err = ioutil.ReadFile(fname)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(textin))
}
英文:

For example,

package main

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

func main() {
	fname := "text.txt"

	// print text file
	textin, err := ioutil.ReadFile(fname)
	if err == nil {
		fmt.Println(string(textin))
	}

	// append text to file
	f, err := os.OpenFile(fname, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
	if err != nil {
		panic(err)
	}
	var textout string
	fmt.Scanln(&textout)
	_, err = f.Write([]byte(textout))
	if err != nil {
		panic(err)
	}
	f.Close()

	// print text file
	textin, err = ioutil.ReadFile(fname)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(textin))
}

答案2

得分: 3

// 读取文件 txt.txt
bs, err := ioutil.ReadFile("text.txt")
if err != nil { // 如果文件不存在,可能需要逻辑来创建文件
panic(err)
}

var userInput []string

var err error = nil
var n int
// 从用户输入中读取多行,直到用户输入 EOF 字符
for ln := ""; err == nil; n, err = fmt.Scanln(ln) {
if n > 0 { // 实际读取了字符串
userInput = append(userInput, ln)
} // 如果没有读取任何内容,可能会设置 err
}

// 打开文件以进行追加
// 0666 对应 Unix 权限 rw-rw-rw-,表示任何人都可以读取或写入它
out, err := os.OpenFile("text.txt", os.O_APPEND, 0666)
defer out.Close() // 无论如何,我们都会在离开作用域时关闭该文件

if err != nil { // 假设文件没有出现问题
// 将每个用户输入行写入文件,后面跟一个换行符
for _, outLn := range userInput {
io.WriteString(out, outLn+"\n")
}
}

我已确保此代码在 play.golang.org 上编译和运行,但我不在我的开发机器上,因此无法验证它是否与 Stdin 和文件的交互完全正确。不过这应该能帮助你入门。

英文:
// reads the file txt.txt 
bs, err := ioutil.ReadFile("text.txt")
if err != nil { //may want logic to create the file if it doesn't exist
      panic(err)
}

var userInput []string

var err error = nil
var n int
//read in multiple lines from user input
//until user enters the EOF char
for ln := ""; err == nil; n, err = fmt.Scanln(ln) {
    if n > 0 {	//we actually read something into the string
        userInput = append(userInput, ln)
    } //if we didn't read anything, err is probably set
}

//open the file to append to it
//0666 corresponds to unix perms rw-rw-rw-,
//which means anyone can read or write it
out, err := os.OpenFile("text.txt", os.O_APPEND, 0666)
defer out.Close() //we'll close this file as we leave scope, no matter what

if err != nil { //assuming the file didn't somehow break
    //write each of the user input lines followed by a newline
	for _, outLn := range userInput {
		io.WriteString(out, outLn+"\n")
	}
}

I've made sure this compiles and runs on play.golang.org, but I'm not at my dev machine, so I can't verify that it's interacting with Stdin and the file entirely correctly. This should get you started though.

答案3

得分: 3

如果您只想将用户的输入附加到文本文件中,您可以像您已经做过的那样读取输入,并使用ioutil.WriteFile来实现,就像您尝试过的那样。所以您已经有了正确的想法。

为了使您的方法可行,简化的解决方案如下:

// 读取旧文本
current, err := ioutil.ReadFile("text.txt")

// 从键盘获取标准输入
var userInput string
fmt.Scanln(&userInput)

// 使用内置的append将新输入附加到旧输入上
newContent := append(current, []byte(userInput)...)

// 现在将输入写回到文件text.txt
err = ioutil.WriteFile("text.txt", newContent, 0666)

WriteFile的最后一个参数是一个标志,用于指定文件的各种选项。高位是文件类型的选项(例如os.ModeDir),低位表示UNIX权限的形式(0666以八进制格式表示用户rw,组rw,其他rw)。有关更多详细信息,请参阅文档

现在您的代码可以工作了,我们可以对其进行改进。例如,通过保持文件打开而不是两次打开:

// 以读写(O_RDRW)方式打开文件,如果文件有内容,则附加到文件末尾,如果文件不存在,则创建文件,使用0666作为创建时的权限。
file, err := os.OpenFile("text.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)

// 当包围函数退出时关闭文件
defer file.Close()

// 读取旧内容
current, err := ioutil.ReadAll(file)

// 对旧内容进行一些操作,例如打印
fmt.Println(string(current))

// 从键盘获取标准输入
var userInput string
fmt.Scanln(&userInput)

// 现在将输入写回到文件text.txt
_, err = file.WriteString(userInput)

这里的魔法是,在打开文件时使用了os.O_APPEND标志,这使得file.WriteString()附加内容。请注意,您需要在打开文件后关闭文件,我们使用defer关键字在函数退出时关闭文件。

英文:

If you simply want to append the user's input to a text file, you could just read the
input as you've already done and use ioutil.WriteFile, as you've tried to do.
So you already got the right idea.

To make your way go, the simplified solution would be this:

// Read old text
current, err := ioutil.ReadFile("text.txt")

// Standard input from keyboard
var userInput string
fmt.Scanln(&userInput)

// Append the new input to the old using builtin `append`
newContent := append(current, []byte(userInput)...)

// Now write the input back to file text.txt
err = ioutil.WriteFile("text.txt", newContent, 0666)

The last parameter of WriteFile is a flag which specifies the various options for
files. The higher bits are options like file type (os.ModeDir, for example) and the lower
bits represent the permissions in form of UNIX permissions (0666, in octal format, stands for user rw, group rw, others rw). See the documentation for more details.

Now that your code works, we can improve it. For example by keeping the file open
instead of opening it twice:

// Open the file for read and write (O_RDRW), append to it if it has
// content, create it if it does not exit, use 0666 for permissions
// on creation.
file, err := os.OpenFile("text.txt", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)

// Close the file when the surrounding function exists
defer file.Close()

// Read old content
current, err := ioutil.ReadAll(file)

// Do something with that old content, for example, print it
fmt.Println(string(current))

// Standard input from keyboard
var userInput string
fmt.Scanln(&userInput)

// Now write the input back to file text.txt
_, err = file.WriteString(userInput)

The magic here is, that you use the flag os.O_APPEND while opening the file,
which makes file.WriteString() append. Note that you need to close the file after
opening it, which we do after the function exists using the defer keyword.

huangapple
  • 本文由 发表于 2012年9月13日 23:42:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/12410014.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定