io.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package util
  2. import (
  3. "io"
  4. "fmt"
  5. "strings"
  6. )
  7. // This function is a well-behaved substitution of fmt.Fscanln.
  8. // The reader is recommended to be a buffered reader because
  9. // this function only reads one character at a time.
  10. // If the given reader is not buffered, this function could perform
  11. // one system call per one character.
  12. // Note that ...[\n][EOF] and ...[EOF] are not distinguished.
  13. func WellBehavedReadLine(f io.Reader) ([]rune, error) {
  14. var buf = make([] rune, 0)
  15. var char rune
  16. for {
  17. var _, err = fmt.Fscanf(f, "%c", &char)
  18. if err != nil {
  19. if err == io.EOF && len(buf) > 0 {
  20. return buf, nil
  21. } else {
  22. return nil, err
  23. }
  24. }
  25. if char != '\n' {
  26. buf = append(buf, char)
  27. } else {
  28. return buf, nil
  29. }
  30. }
  31. }
  32. // standard-library-like version of WellBehavedReadLine
  33. func WellBehavedFscanln(f io.Reader, output *string) (int, error) {
  34. var buf strings.Builder
  35. var total = 0
  36. var one_byte = [] byte { 0 }
  37. for {
  38. var _, err = f.Read(one_byte)
  39. total += 1
  40. if err != nil {
  41. if err == io.EOF && buf.Len() > 0 {
  42. *output = buf.String()
  43. return total, nil
  44. } else {
  45. return total, err
  46. }
  47. }
  48. if rune(one_byte[0]) != '\n' {
  49. buf.WriteByte(one_byte[0])
  50. } else {
  51. *output = buf.String()
  52. return total, nil
  53. }
  54. }
  55. }