Formatted IO with fmt

One of the most widely used packages for IO is fmt (https://golang.org/pkg/fmt). It comes with an amalgam of functions designed for formatted input and output. The most common usage of the fmt package is for writing to standard output and reading from standard input. This section also highlights other functions that make fmt a great tool for IO.

Printing to io.Writer interfaces

The fmt package offers several functions designed to write text data to arbitrary implementations of io.Writer. The fmt.Fprint and fmt.Fprintln functions write text with the default format while fmt.Fprintf supports format specifiers. The following code snippet writes a columnar formatted list of metalloid data to a specified text file using the fmt.Fprintf function:

type metalloid struct { 
   name   string 
   number int32 
   weight float64 
} 
 
func main() { 
   var metalloids = []metalloid{ 
         {"Boron", 5, 10.81}, 
         ... 
         {"Polonium", 84, 209.0}, 
   } 
   file, _ := os.Create("./metalloids.txt") 
   defer file.Close() 
 
   for _, m := range metalloids { 
         fmt.Fprintf( 
               file, 
               "%-10s %-10d %-10.3f
", 
               m.name, m.number, m.weight, 
         ) 
   } 
} 

golang.fyi/ch10/fmtfprint0.go

In the previous example, the fmt.Fprintf function uses format specifiers to write formatted text to the io.File file variable. The fmt.Fprintf function supports a large number of format specifiers whose proper treatment is beyond the scope of this text. Refer to the online documentation for complete coverage of these specifiers.

Printing to standard output

The fmt.Print, fmt.Printf, and fmt.Println have the exact same characteristics as the previous Fprint-series of functions seen earlier. Instead of an arbitrary io.Writer however, they write text to the standard output file handle os.Stdout (see the section Standard output, input, and error covered earlier).

The following abbreviated code snippet shows an updated version of the previous example that writes the list of metalloids to a standard output instead of a regular file. Note that it is the same code except for the use of the fmt.Printf instead of the fmt.Fprintf function:

type metalloid struct { ... } 
func main() { 
   var metalloids = []metalloid{ 
         {"Boron", 5, 10.81}, 
         ... 
         {"Polonium", 84, 209.0}, 
   } 
 
   for _, m := range metalloids { 
         fmt.Printf( 
               "%-10s %-10d %-10.3f
", 
               m.name, m.number, m.weight, 
         ) 
   } 
} 

golang.fyi/ch10/fmtprint0.go

Reading from io.Reader

The fmt package also supports formatted reading of textual data from io.Reader interfaces. The fmt.Fscan and fmt.Fscanln functions can be used to read multiple values, separated by spaces, into specified parameters. The fmt.Fscanf function supports format specifiers for a richer and flexible parsing of data input from io.Reader implementations.

The following abbreviated code snippet uses the function fmt.Fscanf for the formatted input of a space-delimited file (planets.txt) containing planetary data:

func main() { 
   var name, hasRing string 
   var diam, moons int 
 
   // read data 
   data, err := os.Open("./planets.txt") 
   if err != nil { 
         fmt.Println("Unable to open planet data:", err) 
         return 
   } 
   defer data.Close() 
 
   for { 
         _, err := fmt.Fscanf( 
               data, 
               "%s %d %d %s
", 
               &name, &diam, &moons, &hasRing, 
         ) 
         if err != nil { 
               if err == io.EOF { 
                     break 
               } else { 
                     fmt.Println("Scan error:", err) 
                     return 
               } 
         } 
         fmt.Printf( 
               "%-10s %-10d %-6d %-6s
", 
               name, diam, moons, hasRing, 
         ) 
   } 

golang.fyi/ch10/fmtfscan0.go

The code reads from the io.File variable data, until it encounters an io.EOF error indicating the end of the file. Each line of text it reads is parsed using format specifiers "%s %d %d %s " which matches the space-delimited layout of the records stored in the file. Each parsed token is then assigned to its respective variable name, diam, moons, and hasRing, which are printed to the standard output using the fm.Printf function.

Reading from standard input

Instead of reading from an arbitrary io.Reader, the fmt.Scan, fmt.Scanf, and fmt.Scanln are used to read data from standard input file handle, os.Stdin. The following code snippet shows a simple program that reads text input from the console:

func main() { 
   var choice int 
   fmt.Println("A square is what?") 
   fmt.Print("Enter 1=quadrilateral 2=rectagonal:") 
 
   n, err := fmt.Scanf("%d", &choice) 
   if n != 1 || err != nil { 
         fmt.Println("Follow directions!") 
         return 
   } 
   if choice == 1 { 
         fmt.Println("You are correct!") 
   } else { 
         fmt.Println("Wrong, Google it.") 
   } 
} 

golang.fyi/ch10/fmtscan1.go

In the previous program, the fmt.Scanf function parses the input using the format specifier "%d" to read an integer value from the standard input. The function will throw an error if the value read does not match exactly the specified format. For instance, the following shows what happens when character D is read instead of an integer:

$> go run fmtscan1.go
A square is what?
Enter 1=quadrilateral 2=rectagonal: D
Follow directions!
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.88.110