{"record":{"id":"592716e91bb9ff2e","repo":"unknwon/the-way-to-go_ZH_CN","slug":"usage-s-infile-txt-outfile-txt","errorCode":null,"errorMessage":"usage: %s infile.txt outfile.txt","messagePattern":"usage: (.+?) infile\\.txt outfile\\.txt","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"eBook/13.1.md","lineNumber":176,"sourceCode":"```\n\n## 13.1.2 用 fmt 创建错误对象\n\n通常你想要返回包含错误参数的更有信息量的字符串，例如：可以用 `fmt.Errorf()` 来实现：它和 `fmt.Printf()` 完全一样，接收一个或多个格式占位符的格式化字符串和相应数量的占位变量。和打印信息不同的是它用信息生成错误对象。\n\n比如在前面的平方根例子中使用：\n\n```go\nif f < 0 {\n\treturn 0, fmt.Errorf(\"math: square root of negative number %g\", f)\n}\n```\n\n第二个例子：从命令行读取输入时，如果加了 `--help` 或 `-h` 标志，我们可以用有用的信息产生一个错误：\n\n```go\nif len(os.Args) > 1 && (os.Args[1] == \"-h\" || os.Args[1] == \"--help\") {\n\terr = fmt.Errorf(\"usage: %s infile.txt outfile.txt\", filepath.Base(os.Args[0]))\n\treturn\n}\n```\n\n## 链接\n\n- [目录](directory.md)\n- 上一节：[错误处理与测试](13.0.md)\n- 下一节：[运行时异常和 panic](13.2.md)\n","sourceCodeStart":158,"sourceCodeEnd":186,"githubUrl":"https://github.com/unknwon/the-way-to-go_ZH_CN/blob/7a54d34d3657084b6a59e5618bd069b912d571aa/eBook/13.1.md#L158-L186","documentation":"CLI convention example from 13.1.2: when os.Args[1] is -h or --help, the program sets err = fmt.Errorf(\"usage: %s infile.txt outfile.txt\", filepath.Base(os.Args[0])) so the message names the binary (basename only) and the two expected file arguments. It is not an input-processing failure — it is the help/usage path implemented as an error value.","triggerScenarios":"Running the program as prog -h or prog --help. The guard requires len(os.Args) > 1 and only inspects os.Args[1], so 'prog -h extra' also hits it, while 'prog infile -h' does not (the flag is not first) and 'prog' with no args at all shows nothing.","commonSituations":"Users invoking with no arguments see no help (the branch needs a flag); scripts passing flags in later positions bypass help; usage text drifting out of sync with real argument handling; the standard remedy being the flag package, which prints usage on -h and unknown flags automatically.","solutions":["Adopt the standard flag package: flag.Parse() handles -h/--help by printing Usage and exiting — no hand-rolled branch to drift out of date","If keeping the manual check, also handle the zero-argument case, and print help to stdout with exit code 0 for an explicit -h (help is not an error)","Define the usage string once (flag.Usage) and reference it from every branch so text cannot diverge","Scan all arguments for help flags, not just Args[1], if users legitimately pass flags after file names"],"exampleFix":"// before\nif len(os.Args) > 1 && (os.Args[1] == \"-h\" || os.Args[1] == \"--help\") {\n\terr = fmt.Errorf(\"usage: %s infile.txt outfile.txt\", filepath.Base(os.Args[0]))\n\treturn\n}\n\n// after\nflag.Usage = func() {\n\tfmt.Fprintf(os.Stdout, \"usage: %s infile.txt outfile.txt\\n\", filepath.Base(os.Args[0]))\n}\nflag.Parse()","handlingStrategy":"validation","validationCode":"if len(os.Args) < 3 {\n\tflag.Usage()\n\tos.Exit(2)\n}","typeGuard":null,"tryCatchPattern":"if len(os.Args) > 1 && (os.Args[1] == \"-h\" || os.Args[1] == \"--help\") {\n\tfmt.Fprintf(os.Stdout, \"usage: %s infile.txt outfile.txt\\n\", filepath.Base(os.Args[0]))\n\treturn nil // help is a successful exit, not an error\n}","preventionTips":["Prefer the flag package: -h/--help handling and usage printing come for free and stay in sync","Print help to stdout with exit 0; reserve stderr and non-zero codes for real failures","Check argument count early and fail with usage before opening any file","Define usage text once (flag.Usage) and reference it from every branch"],"tags":["go","cli","usage","flag-parsing","fmt-errorf"],"backgroundTag":null,"analyzedSha":"7a54d34d3657084b6a59e5618bd069b912d571aa","analyzedAt":"2026-08-15T15:13:06.026Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}