go語言——輸入輸出


go語言——輸入輸出

輸出

import "fmt"

fmt.Print()    //輸出沒有換行
fmt.Println()  //輸出后換行
fmt.Printf()   //格式化輸出

格式化打印占位符

%v  原樣輸出
%T  打印類型
%t  bool類型
%s  字符串
%f  浮點
%d  10進制
%o  8進制
%x  16進制 0-9 a-f
%X  16進制 0-9 A-F
%b  二進制數
%c  打印字符
%p  打印地址

輸入

import "fmt"

var x int
var y float64
fmt.Scanln(&x)  //阻塞式的輸入,Scanln只會接受一個回車
fmt.Scanf("%d,%f",&x,&y)  //格式化輸入,中間需要輸入""中的符號
fmt.Scan(&x) //從終端獲取輸入,存儲在Scanln中的參數里,空格和換行符作為分隔符


import "bufio"
func main() {
    fmt.Println("請輸入一個字符串:")
    reader := bufio.NewReader(os.Stdin)
    s1, _ := reader.ReadString('\n')
    fmt.Println("讀到的數據:", s1)
}

bufio包

package main

import (
    "bufio"
    "fmt"
    "strings"
    "bytes"
    "io"
)

// bufio 包實現了帶緩存的 I/O 操作

/**
 * 首先看reader和writer基本的結構
 * // Reader implements buffering for an io.Reader object.
 * type Reader struct {
 *  buf          []byte
 *  rd           io.Reader // reader provided by the client
 *  r, w         int       // buf read and write positions
 *  err          error
 *  lastByte     int
 *  lastRuneSize int
 * }
 *
 *
 * // Writer implements buffering for an io.Writer object.
 * // If an error occurs writing to a Writer, no more data will be
 * // accepted and all subsequent writes will return the error.
 * // After all data has been written, the client should call the
 * // Flush method to guarantee all data has been forwarded to
 * // the underlying io.Writer.
 * type Writer struct {
 *  err error
 *  buf []byte
 *  n   int
 *  wr  io.Writer
 * }
 *
 *
 *
 * // ReadWriter 集成了 bufio.Reader 和 bufio.Writer, 實現了 io.ReadWriter 接口
 * type ReadWriter struct {
 *  *Reader
 *  *Writer
 * }
 */

func main()  {
    // 1: 使用bufio.NewReader構造一個reader
    inputReadBuf := strings.NewReader("1234567890")
    reader := bufio.NewReader(inputReadBuf)


    // 2: 使用bufio.NewWriter構造一個writer
    buf := bytes.NewBuffer(make([]byte, 0))
    writer := bufio.NewWriter(buf)


    // 3: 函數Peek函數: 返回緩存的一個Slice(引用,不是拷貝),引用緩存中前n字節數據
    // > 如果引用的數據長度小於 n,則返回一個錯誤信息
    // > 如果 n 大於緩存的總大小,則返回 ErrBufferFull
    // 通過Peek的返回值,可以修改緩存中的數據, 但不能修改底層io.Reader中的數據
    b, err := reader.Peek(5)
    if err != nil {
        fmt.Printf("Read data error")
        return
    }
    // 修改第一個字符
    b[0] = 'A'
    // 重新讀取
    b, _ = reader.Peek(5)
    writer.Write(b)
    writer.Flush()
    fmt.Println("buf(Changed): ", buf, "\ninputReadBuf(Not Changed): ", inputReadBuf)


    // 4: Read函數, 每次讀取一定量的數據, 這個由buf大小覺得, 所以我們可以循環讀取數據, 直到Read返回0說明讀取數據結束
    for {
        b1 := make([]byte, 3)
        n1, _ := reader.Read(b1)
        if n1 <= 0 {
            break
        }
        fmt.Println(n1, string(b1))
    }


    // 5: ReadByte和UnreadByte函數
    // ReadByte 從 b 中讀出一個字節並返回, 如果 b 中無可讀數據,則返回一個錯誤
    // UnreadByte 撤消最后一次讀出的字節, 只有最后讀出的字節可以被撤消, 無論任何操作,只要有內容被讀出,就可以用 UnreadByte 撤消一個字節
    inputReadBuf2 := strings.NewReader("1234567890")
    reader2 := bufio.NewReader(inputReadBuf2)
    // 讀一個字節
    b2, _ := reader2.ReadByte()
    fmt.Println(string(b2))
    // Unread一個字節
    reader2.UnreadByte()
    b2, _ = reader2.ReadByte()
    fmt.Println(string(b2))


    // 6: ReadRune和UnreadRune函數, 類似上面兩個函數
    // ReadRune讀出一個 UTF8 編碼的字符並返回編碼長度, 如果UTF8序列無法解碼出一個正確的Unicode字符, 則只讀出b中的一個字節,size 返回 1
    inputReadBuf3 := strings.NewReader("中文1234567890")
    reader3 := bufio.NewReader(inputReadBuf3)
    b3, size, _ := reader3.ReadRune()
    fmt.Println(string(b3), size)
    reader3.UnreadRune()
    b3, size, _ = reader3.ReadRune()
    fmt.Println(string(b3), size)
    // 執行UnreadRune時候, 如果之前一步不是ReadRune, 那么會報錯, 看下面
    b33, _ := reader3.ReadByte()
    fmt.Println(string(b33))
    err3 := reader3.UnreadRune()
    if err3 != nil {
        fmt.Println("ERR")
    }


    // 7: 讀取緩沖區中數據字節數(只有執行讀才會使用到緩沖區, 否則是沒有的)
    inputReadBuf4 := strings.NewReader("中文1234567890")
    reader4 := bufio.NewReader(inputReadBuf4)
    // 下面返回0, 因為還沒有開始讀取, 緩沖區沒有數據
    fmt.Println(reader4.Buffered())
    // 下面返回strings的整體長度16(一個人中文是3長度)
    reader4.Peek(1)
    fmt.Println(reader4.Buffered())
    // 下面返回15, 因為readByte已經讀取一個字節數據, 所以緩沖區還有15字節
    reader4.ReadByte()
    fmt.Println(reader4.Buffered())
    // 下面的特別有意思: 上面已經讀取了一個字節, 想當於是將"中"讀取了1/3, 那么如果現在使用readRune讀取, 那么
    // 由於無法解析, 那么僅僅讀取一個byte, 所以下面的結果很顯然
    // 第一次: 無法解析, 那么返回一個byte, 所以輸出的是14
    reader4.ReadRune()
    fmt.Println(reader4.Buffered())
    // 第二次讀取, 還剩下"中"最后一個字節, 所以也會err, 所以輸出13
    reader4.ReadRune()
    fmt.Println(reader4.Buffered())
    // 現在"中"讀完了, 那么開始完整讀取"文", 這個OK的, 可以解析的, 所以可以讀取三字節, 那么剩下10字節
    reader4.ReadRune()
    fmt.Println(reader4.Buffered())


    // 8: ReadSlice查找 delim 並返回 delim 及其之前的所有數據的切片, 該操作會讀出數據,返回的切片是已讀出數據的"引用"
    // 如果 ReadSlice 在找到 delim 之前遇到錯誤, 則讀出緩存中的所有數據並返回,同時返回遇到error(通常是 io.EOF)
    // 如果 在整個緩存中都找不到 delim,則返回 ErrBufferFull
    // 如果 ReadSlice 能找到 delim,則返回 nil
    // 注意: 因為返回的Slice數據有可能被下一次讀寫操作修改, 因此大多數操作應該使用 ReadBytes 或 ReadString,它們返回數據copy
    // 不推薦!
    inputReadBuf5 := strings.NewReader("中文123 4567 890")
    reader5 := bufio.NewReader(inputReadBuf5)
    for ; ;  {
        b5 , err := reader5.ReadSlice(' ')
        fmt.Println(string(b5))
        // 讀到最后
        if err == io.EOF {
            break
        }
    }


    // 9: ReadLine 是一個低級的原始的行讀取操作, 一般應該使用 ReadBytes('\n') 或 ReadString('\n')
    // ReadLine 通過調用 ReadSlice 方法實現,返回的也是"引用", 回一行數據,不包括行尾標記(\n 或 \r\n)
    // 如果 在緩存中找不到行尾標記,設置 isPrefix 為 true,表示查找未完成
    // 如果 在當前緩存中找到行尾標記,將 isPrefix 設置為 false,表示查找完成
    // 如果 ReadLine 無法獲取任何數據,則返回一個錯誤信息(通常是 io.EOF)
    // 不推薦!
    inputReadBuf6 := strings.NewReader("中文123\n4567\n890")
    reader6 := bufio.NewReader(inputReadBuf6)
    for ; ;  {
        l, p, err := reader6.ReadLine()
        fmt.Println(string(l), p, err)
        if err == io.EOF {
            break
        }
    }


    // 10: ReadBytes查找 delim 並讀出 delim 及其之前的所有數據
    // 如果 ReadBytes 在找到 delim 之前遇到錯誤, 則返回遇到錯誤之前的所有數據,同時返回遇到的錯誤(通常是 io.EOF)
    // 如果 ReadBytes 找不到 delim 時,err != nil
    // 返回的是數據的copy, 不是引用
    inputReadBuf7 := strings.NewReader("中文123;4567;890")
    reader7 := bufio.NewReader(inputReadBuf7)
    for ; ;  {
        line, err := reader7.ReadBytes(';')
        fmt.Println(string(line))
        if err != nil {
            break
        }
    }


    // 11: ReadString返回的是字符串, 不是bytes
    inputReadBuf8 := strings.NewReader("中文123;4567;890")
    reader8 := bufio.NewReader(inputReadBuf8)
    for ; ;  {
        line, err := reader8.ReadString(';')
        fmt.Println(line)
        if err != nil {
            break
        }
    }


    //12: Flush函數用於提交數據, 立即更新
    // Available函數返回緩存中的可以空間
    // b10是保存數據的數組, 不是writer的緩沖區, 別搞錯了
    b10 := bytes.NewBuffer(make([]byte, 30))
    // 下面會分配4096字節空間緩沖區
    writer10 := bufio.NewWriter(b10)
    writer10.WriteString("1234567890")
    // 此時沒有flush, 那么輸出的是"", 但是緩沖區使用了10個字節, 那么剩下4086, Buffered()返回的是緩沖區還沒有提交的數據, 此處顯然是10
    fmt.Println(writer10.Available(), writer10.Buffered(), b10)
    // 下面flush后, 將緩沖區的數據全部寫入b10中, 緩沖區被清空, 所以緩沖區變成4096, Buffered()返回的是0, 說明數據被寫入
    writer10.Flush()
    fmt.Println(writer10.Available(), writer10.Buffered(), b10)


    // 13: WriteString(...), Write(...), WriteByte(...), WriteRune(...)函數
    // 都是寫數據函數
    b11 := bytes.NewBuffer(make([]byte, 1024))
    writer11 := bufio.NewWriter(b11)
    writer11.WriteString("ABC")
    writer11.WriteByte(byte('M'))
    // Rune的意思是: 代表一個字符, 那么需要一次一個字符寫入
    writer11.WriteRune(rune('好'))
    writer11.WriteRune(rune('么'))
    writer11.Write([]byte("1234567890"))
    writer11.Flush()
    fmt.Println(b11)


    // 14: WriteTo函數
    inputReadBuf9 := strings.NewReader("中文1234567890")
    reader9 := bufio.NewReader(inputReadBuf9)
    b9 := bytes.NewBuffer(make([]byte, 0))
    reader9.WriteTo(b9)
    fmt.Println(b9)


    // 15: ReadFrom函數
    inputReadBuf15 := strings.NewReader("率哪來的順豐內部了第三方吧")
    b15 := bytes.NewBuffer(make([]byte, 0))
    writer15 := bufio.NewWriter(b15)
    writer15.ReadFrom(inputReadBuf15)
    fmt.Println(b15)
}```


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM