• 11-标准库fmt以及文件操作


    标准库fmt包

    输出

    Print

    print系列函数会将内容输出到系统的标准输出,区别在于print函数直接输出内容,Printf函数支持格式化输出字符串,Println函数会在输出内容结尾天际一个换行符。

    //Print
    	fmt.Print("在终端打印该消息。") //没有换行符
    	name := "沙河小王总"
    	fmt.Printf("我是:%s\n", name)
    	fmt.Println("在终端打印单独一行显示。") //有换行符
    
    //运行结果
    在终端打印该消息。我是:沙河小王总
    在终端打印单独一行显示。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    Fprint

    Fprint系列函数会将内容输出到接口类型的变量w中,通常用这个函数往文件中写入内容。

    //Fprint
    	//向标准输出写入内容
    	fmt.Fprintln(os.Stdout, "向标准输出写入内容")
    	file, err := os.OpenFile("./xxx.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
    	if err != nil {
    		fmt.Println(err)
    		return
    	}
    	name1 := "沙河小王子"
    	//向打开文件写内容
    	fmt.Fprintf(file, "往文件写入:%s", name1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    Sprint

    Sprint系列函数会把传入的数据生成并返回一个字符串。

    //Sprint
    	s1 := fmt.Sprint("沙河小王子")
    	name2 := "沙河小王子"
    	age := 18
    	s2 := fmt.Sprintf("name:%s,age:%d", name2, age)
    
    	s3 := fmt.Sprintln("沙河小王子")
    	fmt.Println(s1, s2, s3)
    
    //运行结果
    沙河小王子 name:沙河小王子,age:18 沙河小王子
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    格式化占位符

    *printf系列函数都支持format格式化参数,在这里我们按照占位符将被替换的变量类型划分,方便查询和记忆。

    通用占位符
    占位符说明
    %v值的默认格式表示
    %+v类似%v,但输出结构体时会添加字段名
    %#v值的Go语法表示
    %T打印值的类型
    %%百分号

    示例代码如下:

    fmt.Printf("%v\n", 100)
    	fmt.Printf("%v\n", false)
    	o := struct{ name string }{"小昂子"}
    	fmt.Printf("%v\n", o)
    	fmt.Printf("%#v\n", o)
    	fmt.Printf("%T\n", o)
    	fmt.Printf("100%%\n")
    
    //运行结果:
    100
    false
    {小昂子}
    struct { name string }{name:"小昂子"}
    struct { name string }
    100%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    布尔型
    占位符说明
    %ttrue或false
    整型
    占位符说明
    %b表示为二进制
    %c该值对应的unicode码值
    %d表示为十进制
    %o表示为八进制
    %x表示为十六进制,使用a-f
    %X表示为十六进制,使用A-F
    %U表示为Unicode格式:U+1234,等价于”U+%04X”
    %q该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示

    示例代码

    n := 65
    	fmt.Printf("%b\n", n)
    	fmt.Printf("%c\n", n)
    	fmt.Printf("%d\n", n)
    	fmt.Printf("%o\n", n)
    	fmt.Printf("%x\n", n)
    	fmt.Printf("%X\n", n)
    
    
    //运行结果:
    1000001
    A
    65
    101
    41
    41
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    浮点数与复数
    占位符说明
    %b无小数部分、二进制指数的科学计数法,如-123456p-78
    %e科学计数法,如-1234.456e+78
    %E科学计数法,如-1234.456E+78
    %f有小数部分但无指数部分,如123.456
    %F等价于%f
    %g根据实际情况采用%e或%f格式(以获得更简洁、准确的输出)
    %G根据实际情况采用%E或%F格式(以获得更简洁、准确的输出)
    字符串和[]byte
    占位符说明
    %s直接输出字符串或者[]byte
    %q该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示
    %x每个字节用两字符十六进制数表示(使用a-f
    %X每个字节用两字符十六进制数表示(使用A-F)

    示例代码如下:

    s := "小王子"
    	fmt.Printf("%s\n", s)
    	fmt.Printf("%q\n", s)
    	fmt.Printf("%x\n", s)
    	fmt.Printf("%X\n", s)
    
    //运行结果
    小王子
    "小王子"
    e5b08fe78e8be5ad90
    E5B08FE78E8BE5AD90
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    指针
    占位符说明
    %p表示为十六进制,并加上前导的0x
    宽度标识符

    宽度通过一个紧跟在百分号后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过(可选的)宽度后跟点号后跟的十进制数指定。如果未指定精度,会使用默认精度;如果点号后没有跟数字,表示精度为0。举例如下:

    占位符说明
    %f默认宽度,默认精度
    %9f宽度9,默认精度
    %.2f默认宽度,精度2
    %9.2f宽度9,精度2
    %9.f宽度9,精度0
    n := 12.34
    	fmt.Printf("%f\n", n)
    	fmt.Printf("%9f\n", n)
    	fmt.Printf("%.2f\n", n)
    	fmt.Printf("%9.2f\n", n)
    	fmt.Printf("%9.f\n", n)
    
    
    //运行结果
    12.340000
    12.340000
    12.34
        12.34
           12
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    其他flag

    占位符说明
    ’+’总是输出数值的正负号;对%q(%+q)会生成全部是ASCII字符的输出(通过转义);
    ’ ‘对数值,正数前加空格而负数前加负号;对字符串采用%x或%X时(% x或% X)会给各打印的字节之间加空格
    ’-’在输出右边填充空白而不是默认的左边(即从默认的右对齐切换为左对齐);
    ’#’八进制数前加0(%#o),十六进制数前加0x(%#x)或0X(%#X),指针去掉前面的0x(%#p)对%q(%#q),对%U(%#U)会输出空格和单引号括起来的go字面值;
    ‘0’使用0而不是空格填充,对于数值类型会把填充的0放在正负号后面;

    输入

    Go语言fmt包下有fmt.Scan fmt.Scanffmt.Scanln三个函数,可以在程序运行过程中从标准输入获取用户的输入。

    fmt.Scan
    • Scan从标准输入扫描文本,读取由空白符分隔的值保存到传递给本函数的参数中,换行符视为空白符。
    • 本函数返回成功扫描的数据个数和遇到的任何错误。如果读取的数据个数比提供的参数少,会返回一个错误报告原因。
    var (
    		name     string
    		age      int
    		marraied bool
    	)
    	fmt.Scan(&name, &age, &marraied)
    	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, marraied)
    
    //运行结果
    王磊 23 true
    扫描结果 name:王磊 age:23 married:true 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    fmt.Scanf

    函数签名如下:

    func Scanf(format string, a ...interface{}) (n int, err error)
    
    • 1
    • Scanf从标准输入扫描文本,根据format参数指定的格式去读取由空白符分隔的值保存到传递给本函数的参数中。
    • 本函数返回成功扫描的数据个数和遇到的任何错误。

    代码示例如下:

    func main() {
    	var (
    		name    string
    		age     int
    		married bool
    	)
    	fmt.Scanf("1:%s 2:%d 3:%t", &name, &age, &married)
    	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    将上面的代码编译后在终端执行,在终端按照指定的格式依次输入小王子28false

    $ ./scan_demo 
    1:小王子 2:28 3:false
    扫描结果 name:小王子 age:28 married:false 
    
    • 1
    • 2
    • 3

    fmt.Scanf不同于fmt.Scan简单的以空格作为输入数据的分隔符,fmt.Scanf为输入数据指定了具体的输入内容格式,只有按照格式输入数据才会被扫描并存入对应变量。

    fmt.Scanln

    函数签名如下:

    func Scanln(a ...interface{}) (n int, err error)
    
    • 1
    • Scanln类似Scan,它在遇到换行时才停止扫描。最后一个数据后面必须有换行或者到达结束位置。
    • 本函数返回成功扫描的数据个数和遇到的任何错误。

    具体代码示例如下:

    func main() {
    	var (
    		name    string
    		age     int
    		married bool
    	)
    	fmt.Scanln(&name, &age, &married)
    	fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    将上面的代码编译后在终端执行,在终端依次输入小王子28false使用空格分隔。

    $ ./scan_demo 
    小王子 28 false
    扫描结果 name:小王子 age:28 married:false 
    
    • 1
    • 2
    • 3

    fmt.Scanln遇到回车就结束扫描了,这个比较常用。

    文件操作

    打开和关闭文件

    os.Open()函数能够打开一个文件,返回一个*File和一个err。对得到的文件实例调用close()方法能够关闭文件。

    //只读方式打开当前目录下的main.go文件
    	file, err := os.Open("./main.go")
    	if err != nil {
    		fmt.Println("open fail:", err)
    		return
    	}
    
    	//关闭文件
    	file.Close()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    为了防止文件忘记关闭,我们通常使用defer注册文件关闭语句。

    读取文件
    file.Read()

    Read方法定义如下:

    func (f *File) Read(b []byte) (n int, err error)
    
    • 1

    它接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0io.EOF。 举个例子:

    基本使用:

    //只读方式打开当前目录下的main.go文件
    	file, err := os.Open("./main.go")
    	if err != nil {
    		fmt.Println("打开文件失败", err)
    		return
    	}
    
    	defer file.Close()
    
    	//使用Read方法读取数据
    	var tmp = make([]byte, 128)
    	n, err := file.Read(tmp)
    	if err == io.EOF {
    		fmt.Println("文件读完了")
    		return
    	}
    
    	if err != nil {
    		fmt.Println("读取文件失败", err)
    		return
    	}
    	fmt.Printf("读取了%d字节\n", n)
    	fmt.Println(string(tmp[:n]))
    
    
    //运行结果
    读取了128字节
    package main
    
    func main() {
            // fmtDemo()
            // fmtDemo2()
            // fmtDemo3()
            // fmtDemo4()
            // fmtDemo5()
            // fmtDemo6()
            // fileDem
    
    • 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

    循环读取:

    //只读方式打开文件
    	file, err := os.Open("./main.go")
    	if err != nil {
    		fmt.Println("打开文件失败", err)
    		return
    	}
    	defer file.Close()
    
    	//循环读取文件
    	var content []byte
    	var tmp = make([]byte, 128)
    	for {
    		n, err := file.Read(tmp)
    		if err != io.EOF {
    			fmt.Println("文件读完了")
    			break
    		}
    		if err != nil {
    			fmt.Println("读取文件失败", err)
    			return
    		}
    		content = append(content, tmp[:n]...)
    	}
    	fmt.Println(string(content))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    bufio读取文件

    bufio是在file的基础上封装了一层API,支持更多的功能。

    逐行读取:

    //bufio按行读取
    	file, err := os.Open("./main.go")
    	if err != nil {
    		fmt.Println("打开文件失败", err)
    		return
    	}
    	defer file.Close()
    	reader := bufio.NewReader(file)
    
    	for {
    		line, err := reader.ReadString('\n') //注意是字符
    		if err == io.EOF {
    			if len(line) != 0 {
    				fmt.Println(line)
    			}
    			fmt.Println("文件读完了")
    			break
    		}
    
    		if err != nil {
    			fmt.Println("读取文件失败", err)
    			return
    		}
    		fmt.Print(line)
    	}
    
    //运行结果
    package main
    
    func main() {
            // fmtDemo()
            // fmtDemo2()
            // fmtDemo3()
            // fmtDemo4()
            // fmtDemo5()
            // fmtDemo6()
            // fileDemo()
            // fileDemo2()
            // fileDemo3()
            fileDemo4()
    }
    文件读完了
    
    • 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
    • 39
    • 40
    • 41
    • 42
    ioutil读取整个文件

    io/ioutil包的ReadFile方法能够读取完整的文件,只需要将文件名作为参数传入。

    //iountil.ReadFile读取整个文件
    
    	content, err := ioutil.ReadFile("./main.go")
    
    	if err != nil {
    		fmt.Println("读取文件失败", err)
    		return
    	}
    
    	fmt.Println(string(content))
    //运行结果
    package main
    
    func main() {
            // fmtDemo()
            // fmtDemo2()
            // fmtDemo3()
            // fmtDemo4()
            // fmtDemo5()
            // fmtDemo6()
            // fileDemo()
            // fileDemo2()
            // fileDemo3()
            // fileDemo4()
            fileDemo5()
    }
    
    • 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
    文件写入操作

    os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能。

    func OpenFile(name string, flag int, perm FileMode) (*File, error) {
    	...
    }
    
    • 1
    • 2
    • 3

    其中:

    name:要打开的文件名 flag:打开文件的模式。 模式有以下几种:

    模式含义
    os.O_WRONLY只写
    os.O_CREATE创建文件
    os.O_RDONLY只读
    os.O_RDWR读写
    os.O_TRUNC清空
    os.O_APPEND追加

    perm:文件权限,一个八进制数。r(读)04,w(写)02,x(执行)01。

    Write和WriteString
    file, err := os.OpenFile("xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    
    	if err != nil {
    		fmt.Println("打开文件失败", err)
    		return
    	}
    
    	defer file.Close()
    
    	str := "hellp 沙河"
    	file.Write([]byte(str)) //写入字节切片数据
    	file.WriteString(str)   //直接写入字符串数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    Buffo.NewWrite
    file, err := os.OpenFile("./xx.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
    
    	if err != nil {
    		fmt.Println("打开失败", err)
    		return
    	}
    	defer file.Close()
    
    	writer := bufio.NewWriter(file)
    
    	for i := 0; i < 10; i++ {
    		writer.WriteString("hellp 沙河小王总\n") //将数据写入缓存中
    	}
    	writer.Flush() //将数据写入文件中
    
    //运行结果
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    hellp 沙河小王总
    
    
    • 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
    ioutil.WriteFile
    str := "沙河小王子"
    	err := ioutil.WriteFile("./xxx.txt", []byte(str), 0666)
    
    	if err != nil {
    		fmt.Println("写入文件失败", err)
    		return
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EL9lTooj-1656636280567)(day05.assets/image-20220213122309703.png)]

  • 相关阅读:
    MySQL 的执行原理(五)
    C_指针基础5
    服务器的架构有哪些
    Linux——指令初识(二)
    中国微单相机行业市场深度分析及发展规划咨询综合研究报告
    【mybatis】mybatis的特性和优势
    Java开发学习(二十五)----使用PostMan完成不同类型参数传递
    【QT】Qt读取ANSI格式文件
    「 GCC编译工具」
    helm 简介与入门
  • 原文地址:https://blog.csdn.net/weixin_38753143/article/details/125551809