标准输出 vs 标准错误

  • 标准输出:stdout
    • println!
  • 标准错误:stderr
    • eprintln!

      标准输出重定向:cargo run > output.txt

  1. use minigrep::Config;
  2. use std::env;
  3. use std::process;
  4. fn main() {
  5. let args: Vec<String> = env::args().collect();
  6. let config = Config::new(&args).unwrap_or_else(|err| {
  7. eprintln!("Problem parsing arguments: {}", err);
  8. process::exit(1);
  9. });
  10. if let Err(e) = minigrep::run(config) {
  11. eprintln!("Application error: {}", e);
  12. process::exit(1);
  13. }
  14. }
  1. use std::env;
  2. use std::error::Error;
  3. use std::fs;
  4. pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
  5. let contents = fs::read_to_string(config.filename)?;
  6. let results = if config.case_sensitive {
  7. search(&config.query, &contents)
  8. } else {
  9. search_case_insensitive(&config.query, &contents)
  10. };
  11. for line in results {
  12. println!("{}", line);
  13. }
  14. Ok(())
  15. }
  16. pub struct Config {
  17. pub query: String,
  18. pub filename: String,
  19. pub case_sensitive: bool,
  20. }
  21. impl Config {
  22. pub fn new(args: &[String]) -> Result<Config, &'static str> {
  23. if args.len() < 3 {
  24. return Err("not enough arguments");
  25. }
  26. let query = args[1].clone();
  27. let filename = args[2].clone();
  28. let case_sensitive = env::var("CASE_INSENSITIVE").is_err();
  29. Ok(Config {
  30. query,
  31. filename,
  32. case_sensitive,
  33. })
  34. }
  35. }
  36. pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
  37. let mut results = Vec::new();
  38. for line in contents.lines() {
  39. if line.contains(query) {
  40. results.push(line);
  41. }
  42. }
  43. results
  44. }
  45. pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
  46. let mut results = Vec::new();
  47. let query = query.to_lowercase();
  48. for line in contents.lines() {
  49. if line.to_lowercase().contains(&query) {
  50. results.push(line);
  51. }
  52. }
  53. results
  54. }
  55. #[cfg(test)]
  56. mod tests {
  57. use super::*;
  58. #[test]
  59. fn case_sensitive() {
  60. let query = "duct";
  61. let contents = "\
  62. Rust:
  63. safe, fast, productive.
  64. Pick three.
  65. Duct tape.";
  66. assert_eq!(vec!["safe, fast, productive."], search(query, contents));
  67. }
  68. #[test]
  69. fn case_insensitive() {
  70. let query = "rUst";
  71. let contents = "\
  72. Rust:
  73. safe, fast, productive.
  74. Pick three.
  75. Trust me.";
  76. assert_eq!(
  77. vec!["Rust:", "Trust me."],
  78. search_case_insensitive(query, contents)
  79. );
  80. }
  81. }