I have a bufio scanner on a StringReader. After I reach a certain line on the Scanner output, I want to read until the end of the reader. Is there any way to achieve this using a simpler way, other than the commented code ?
s := `1
2
3
4
5
6
7`
beyond5 := ""
scanner := bufio.NewScanner(strings.NewReader(s))
for scanner.Scan() {
if strings.Contains(scanner.Text(), "5") {
// Read all lines until EOF from scanner
// and store in beyond5
// for scanner.Scan() {
// beyond5 += scanner.Text()
// beyond5 += "
"
// }
break
}
}
log.Println(beyond5)
It seems such an operation is not possible at all with the scanner. We need to use the bufio reader only. The code is:
s := `1
2
3
4
5
6
7`
beyond5 := ""
r := strings.NewReader(s)
reader := bufio.NewReader(r)
for {
line, err := reader.ReadString('
')
if err != nil {
log.Fatal(err)
}
if strings.Contains(line, "5") {
b, _ := ioutil.ReadAll(reader)
beyond5 = string(b)
break
}
}
log.Println(beyond5)
Is this that you want? :-)
s := `1
2
3
4
5
6
7`
var beyond5 string
if strings.Contains(s, "5") {
scanner := bufio.NewScanner(strings.NewReader(s))
for scanner.Scan() {
beyond5 += scanner.Text()
}
}
beyond5 += "
"
log.Println(beyond5)
UPDATE: My solution is similar to @abhink's solution, however, they are different solutions
I have used Split method, this method set split (private) property that it is SplitFunc type. And this is my implementation:
var canPass bool
func mySplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
for pos, value := range data {
if (value < '6' && !canPass) || (value < '0' || value > '9') {
continue
}
canPass = true
return pos+1, data[pos : pos + 1], nil
}
return 0, nil, nil
}
Now, you must use Split method, send it mySplit as parameter.
scanner.Split(mySplit)
And you do a simple for with scanner.Scan()
for scanner.Scan() {
beyond5 += scanner.Text() + "
"
}
Output:
6
7
I hope it is the solution that you were looking for :-)