Exercise 5 of 10 · Reading input and strings
Poem Word Counter
What you will make
A program that reads one line of a poem from standard input (or falls back to a default line when there's no input) and reports how many words are in it.
The one new idea: Reading a line with bufio, cleaning it with strings.TrimSpace, and splitting it into words with strings.Fields
Reading a line of text and breaking it into words is the starting point for almost any program that processes real text, from word counters to simple search tools.
Go straight to the code ↓Reading text in Go usually starts with a bufio.Reader wrapped around os.Stdin, and ReadString('\n') reads up to and including the next newline character — which is why the very next step is almost always strings.TrimSpace to strip that newline (and any stray spaces) off the ends. Once you have a clean line, strings.Fields splits it into a slice of words, breaking on any run of whitespace, which is exactly what you want for counting words with len.
Because automated environments don't always have a person typing at the keyboard, it's good practice to handle the case where there's no input at all — that's what the if line == "" check and fallback line are for here.
Worked example
Here's the same read-clean-split-count pattern with a different fallback line:
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
line, _ := reader.ReadString('\n')
line = strings.TrimSpace(line)
if line == "" {
line = "Two roads diverged in a wood"
}
words := strings.Fields(line)
fmt.Println("Poem line:", line)
fmt.Println("Word count:", len(words))
}Poem line: Two roads diverged in a wood
Word count: 6Six words, split cleanly on the spaces between them.
Your turn
The starter program is supposed to fall back to a default poem line whenever there's no real input, then count the words in whatever line it ends up with — but the empty check is backwards, and the splitting function chops the line into characters instead of words. Fix both marked lines.
If something goes wrong
If the poem line printed is empty, your if condition is probably still testing for the wrong thing — it should trigger the fallback when the line IS empty. If the word count looks far too high (dozens instead of a handful), you're likely still splitting into individual characters rather than words; swap in strings.Fields.
Write your code
Runs in your browser. Press Run (or Ctrl/Cmd+Enter) and the output is checked for you.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.The runtime is starting in the background. You can type now — it will be ready before you are.
The answer appears here once you have run your code at least once.
Things that often go wrong here
- Flipping == and != in a condition meant to detect an empty value.
- These are opposite tests; using the wrong one makes the fallback trigger in exactly the cases it shouldn't.
- Reaching for strings.Split(text, "") to get words.
- An empty separator splits between every character, not at whitespace boundaries — strings.Fields is the function built for word-splitting, and it also collapses repeated spaces.
- Forgetting that bufio's ReadString keeps the delimiter.
- ReadString('\n') includes the newline character in the string it returns, so comparisons or word counts done before TrimSpace can be off by one character.
- Assuming there will always be real keyboard input to read.
- In an automated environment, standard input can be empty and reading it hits end-of-file immediately — programs that read input should handle that gracefully, as this one does with its fallback line.
Want a blank editor instead? Open the Go playground.