You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
2.0 KiB
Go

package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io"
"os"
"slices"
"unicode/utf8"
)
func byteCounter(f *os.File) {
fileInfo, err := f.Stat()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
fmt.Println(fileInfo.Size())
}
func lineCounter(f io.Reader) {
buf := make([]byte, 32*1024)
count := 0
lineSep := []byte{'\n'}
for {
c, err := f.Read(buf) // c==0 if EOF
switch {
case err == io.EOF:
fmt.Println(count)
return
case err != nil:
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
count += bytes.Count(buf[:c], lineSep)
}
}
func wordCounter(f io.Reader) {
buf := make([]byte, 32*1024)
count := 0
wordSep := []byte{' ', '\t', '\n', '\r', '\f', '\v'}
inWord := false
for {
c, err := f.Read(buf)
switch {
case err == io.EOF:
if inWord {
count++
}
fmt.Println(count)
return
case err != nil:
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
for _, b := range buf[:c] {
if slices.Contains(wordSep, b) {
if inWord {
count++
}
inWord = false
} else {
inWord = true
}
}
}
}
func charCounter(f *os.File) {
var line string
var err error
r := bufio.NewReader(f)
count := 0
for err == nil {
line, err = r.ReadString('\n')
count += utf8.RuneCountInString(line)
}
if err != io.EOF {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
fmt.Println(count)
}
func main() {
cFlag := flag.Bool("c", false, "print the byte count")
lFlag := flag.Bool("l", false, "print the line count")
wFlag := flag.Bool("w", false, "print the word count")
mFlag := flag.Bool("m", false, "print the character count")
flag.Parse()
fileName := flag.Arg(0)
if len(fileName) == 0 {
fmt.Fprintf(os.Stderr, "gowc [flags] filename\n")
flag.Usage()
os.Exit(1)
}
f, err := os.Open(fileName)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
defer f.Close()
switch {
case *cFlag:
byteCounter(f)
case *lFlag:
lineCounter(f)
case *wFlag:
wordCounter(f)
case *mFlag:
charCounter(f)
}
}