问题描述
我一直试图弄清楚如何实现我最初认为是简单的程序.我有一个引号的文本文件,所有引号均以"$$"
I have been trying to figure out how to implement what I originally thought would be a simple program.I have a text file of quotations that are all separated by ‘$$’
我希望程序解析报价文件并随机选择3个引号来显示和标准输出.
I want the program to parse the quotation file and randomly select 3 quotes to display and standard output.
文件中有1022个引号.
There are 1022 quotes in the file.
当我尝试分割文件时,出现此错误:缺少"
我似乎无法弄清楚如何为$$分配字符串文字,我不断得到:
缺少"
I can’t seem to figure out how to assign $$ with a string literal, I keep getting:
missing '
这是自定义扫描仪:
onDollarSign := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
for i := 0; i < len(data); i++ {
//if data[i] == "$$" { # this is what I did originally
//if data[i:i+2] == "$$" { # (mismatched types []byte and string)
//if data[i:i+2] == `$$` { # throws (mismatched types []byte and string)
// below throws syntax error: unexpected $ AND missing '
if data[1:i+2] == '$$' {
return i + 1, data[:i], nil
}
}
如果我仅使用一个 $
,则字符串文字可以正常工作.
The string literal works fine if I only use one $
.
由于某些原因,仅将71个报价加载到报价切片中.我不确定如何扩展.允许将所有1022个引用都存储在内存中.
For some reason only 71 quotations are loaded into the quotes slice. I'm not sure how to expand. To allow all 1022 quotes to be stored in memory.
我一直很难解决这个问题.这就是我现在所拥有的:
I've been having a really difficult time trying to figure out how to do this. this is what I have right now:
package main
import (
"bufio"
"fmt"
"log"
"math/rand"
"os"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano()) // Try changing this number!
quote_file, err := os.Open("/Users/bryan/Dropbox/quotes_file.txt")
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(quote_file)
// define split function
onDollarSign := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
for i := 0; i < len(data); i++ {
if data[i] == '$$' {
return i + 1, data[:i], nil
}
}
fmt.Print(data)
return 0, data, bufio.ErrFinalToken
}
scanner.Split(onDollarSign)
var quotes []string
// I think this will scan the file and append all the parsed quotes into quotes
for scanner.Scan() {
quotes = append(quotes, scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading input:", err)
}
fmt.Print(len(quotes))
fmt.Println("quote 1:", quotes[rand.Intn(len(quotes))])
fmt.Println("quote 2:", quotes[rand.Intn(len(quotes))])
fmt.Println("quote 3:", quotes[rand.Intn(len(quotes))])
}
推荐答案
如果最终还是要读取整个文件,则使用扫描仪是一件令人费解的事情.我将阅读整个文件,然后将其拆分为引号列表:
Using a scanner if you end up reading the whole file anyway is kind of convoluted. I'd read the whole file and then simply split it into the list of quotes:
package main
import (
"bytes"
"io/ioutil"
"log"
"math/rand"
"os"
)
func main() {
// Slurp file.
contents, err := ioutil.ReadFile("/Users/bryan/Dropbox/quotes_file.txt")
if err != nil {
log.Fatal(err)
}
// Split the quotes
separator := []byte("$$") // Convert string to []byte
quotes := bytes.Split(contents, separator)
// Select three random quotes and write them to stdout
for i := 0; i < 3; i++ {
n := rand.Intn(len(quotes))
quote := quotes[n]
os.Stdout.Write(quote)
os.Stdout.Write([]byte{'\n'}) // new line, if necessary
}
}
如果在阅读文件之前 选择了三个引号,则使用扫描仪将很有意义.那么您可以在到达最后一个报价后停止阅读.
Using a scanner would make sense if you selected three quotes before reading the file; then you can stop reading after you have reached the last quote.
这篇关于如何使用Golang自定义扫描器字符串文字并扩展内存以将整个文件加载到内存中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!