Printf weirdness

I’m really new to Go and reading the book, “The Go Programming Language”.

One exercise had me modifying code to capture filenames along with the count of duplicate lines.

My problem with the code below is the following three lines:

			s := fmt.Sprintf("%d\t", n)
			s += fmt.Sprintf("%s\n", line)
			s += fmt.Sprintln(files[line])

if I change the second line to

			s += fmt.Sprintf("%s\t", line)

it only outputs the file names (the last line). I’ve tried single line versions for Printf, Sprintf and the multi-line versions with Print and Println, they all do the same thing. I’m using go version 1.9.2 on Windows. Searching didn’t seem to uncover limits with the Print functions. Any pointers on what I should look for next or what I’m doing wrong would be appreciated.


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

func main() {
	counts := make(map[string]int)
	files := make(map[string]string)
	for _, filename := range os.Args[1:] {
		data, err := ioutil.ReadFile(filename)
		if err != nil {
			fmt.Fprintf(os.Stderr, "dup3: %v\n", err)
			continue
		}
		for _, line := range strings.Split(string(data), "\n") {
			counts[line]++
			files[line] += " " + filename
		}
	}
	for line, n := range counts {
		if n > 1 {
			s := fmt.Sprintf("%d\t", n)
			s += fmt.Sprintf("%s\n", line)
			s += fmt.Sprintln(files[line])
			fmt.Print(s)
		}
	}
}

Here’s a one line version using Printf

			// Only outputs files[line]
			fmt.Printf("%d\t%s\t%s", n, line, files[line])

Here’s a version printing each value

			// Only outputs files[line]
			fmt.Print(n)
			fmt.Print("\t")
			fmt.Print(line)
			fmt.Print("\t")
			fmt.Print(files[line])

Here’s a couple versions that work:

			fmt.Printf("%d\t%s\n%s", n, line, files[line])

and

			fmt.Println(n)
			fmt.Println(line)
			fmt.Println(files[line])

Just when I try to put them on one line, it outputs only the last element.

Found it, thanks Windows! Text files in windows are \r\n. So line at \r in them which started printing the line over again.

I changed

		for _, line := range strings.Split(string(data), "\n") {

to

		for _, line := range strings.Split(string(data), "\r\n") {

and all the print versions worked as expected.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.