在Golang程序中,命令行参数无法正确接受为参数。

huangapple go评论122阅读模式
英文:

Command line parameter not accepting as arguments properly in Golang program

问题

我是你的中文翻译助手,以下是翻译好的内容:

我刚开始学习Golang,并且在网上参考教程制作一个简单的命令行终端问答应用程序。然而,当我在我的电脑上运行代码时,第一个问题之后,剩下的问题都是成对出现的,并且不再接受我的答案。

程序的流程非常简单:

  1. 从本地的csv文件中获取问题。
  2. 打印每个问题,并获取用户输入的答案。
  3. 统计正确答案的数量,并在最后显示。

csv文件也很简短:

70+22,92
63+67,130
91+72,163
74+61,135
81+6,87

以下是完整的程序代码:

package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"os"
	"time"
)

func main() {
	// 1. 输入文件名
	fName := flag.String("f", "quiz.csv", "csv文件路径")
	// 2. 设置计时器的时长
	timer := flag.Int("t", 30, "问答计时器")
	flag.Parse()
	// 3. 从文件中读取问题(调用问题获取函数)
	problems, err := problemPuller(*fName)
	// 4. 处理错误
	if err != nil {
		exit(fmt.Sprintf("出错了:%s", err.Error()))
	}
	// 5. 创建变量来统计正确答案的数量
	correctAns := 0
	// 6. 使用计时器的时长,初始化计时器
	tObj := time.NewTimer(time.Duration(*timer) * time.Second)
	ansC := make(chan string)
	// 7. 遍历问题,打印问题,接受答案
problemLoop:
	for i, p := range problems {
		var answer string
		fmt.Printf("问题 %d: %s =", i+1, p.question)

		go func() {
			fmt.Scanf("%s", &answer)
			ansC <- answer
		}()
		select {
		case <-tObj.C:
			fmt.Println()
			break problemLoop
		case iAns := <-ansC:
			if iAns == p.answer {
				correctAns++
			}
			if i == len(problems)-1 {
				close(ansC)
			}
		}
	}
	// 8. 计算并打印结果
	fmt.Printf("你的得分是 %d 分(满分 %d 分)\n", correctAns, len(problems))
	fmt.Printf("按回车键退出")
	<-ansC
}

func problemPuller(fileName string) ([]problem, error) {
	// 从quiz.csv文件中读取所有问题

	// 1. 打开文件
	if fObj, err := os.Open(fileName); err == nil {
		// 2. 创建新的读取器
		csvR := csv.NewReader(fObj)
		// 3. 读取文件内容
		if cLines, err := csvR.ReadAll(); err == nil {
			// 4. 调用parseProblem函数
			return parseProblem(cLines), nil
		} else {
			return nil, fmt.Errorf("从文件 %s 读取csv数据时出错:%s", fileName, err.Error())
		}
	} else {
		return nil, fmt.Errorf("打开文件 %s 时出错:%s", fileName, err.Error())
	}
}

func parseProblem(lines [][]string) []problem {
	// 遍历每行并根据问题结构进行解析
	r := make([]problem, len(lines))
	for i := 0; i < len(lines); i++ {
		r[i] = problem{
			question: lines[i][0],
			answer:   lines[i][1],
		}
	}
	return r
}

type problem struct {
	question string
	answer   string
}

func exit(msg string) {
	fmt.Println(msg)
	os.Exit(1)
}

我尝试逐行检查代码,但是我无法解决问题。请问有人可以指出我做错了什么吗?

英文:

I am new to Golang and was following a tutorial online about making a simple quiz application using the command line terminal. However, when I run the code on my machine, after the 1st question, the rest of the questions come in pairs and it is not accepting my answer to each question anymore.

Sample screenshot:

在Golang程序中,命令行参数无法正确接受为参数。

The flow of the program is quite simple -

  1. Take input questions from a local csv file
  2. Print each question and take user input for the answer
  3. Maintain count of correct answers and display them at the end.

The csv file is quite short too -

70+22,92
63+67,130
91+72,163
74+61,135
81+6,87

Here is the complete program -

package main
import (
&quot;encoding/csv&quot;
&quot;flag&quot;
&quot;fmt&quot;
&quot;os&quot;
&quot;time&quot;
)
func main() {
// 1. input the name of the file
fName := flag.String(&quot;f&quot;, &quot;quiz.csv&quot;, &quot;path of csv file&quot;)
// 2. set the duration of timer
timer := flag.Int(&quot;t&quot;, 30, &quot;timer for the quiz&quot;)
flag.Parse()
// 3. pull the problems from the file  (calling our problem puller)
problems, err := problemPuller(*fName)
// 4. handle the error
if err != nil {
exit(fmt.Sprintf(&quot;something went wrong: %s&quot;, err.Error()))
}
// 5. create a variable to count our correct answers
correctAns := 0
// 6. using the duration of the timer, we want to initialize the timer
tObj := time.NewTimer(time.Duration(*timer) * time.Second)
ansC := make(chan string)
// 7. loop through the problems, print the questions, we&#39;ll accept the answers
problemLoop: 
for i, p := range problems {
var answer string
fmt.Printf(&quot;Problem %d: %s =&quot;, i+1, p.question)
go func() {
fmt.Scanf(&quot;%s&quot;, &amp;answer)
ansC &lt;- answer
}()
select {
case &lt;- tObj.C:
fmt.Println()
break problemLoop
case iAns := &lt;- ansC:
if iAns == p.answer {
correctAns++
}
if i == len(problems)-1 {
close(ansC)
}
}
}
// 8. calculate and print out the result
fmt.Printf(&quot;Your result is %d out of %d\n&quot;, correctAns, len(problems))
fmt.Printf(&quot;Press enter to exit&quot;)
&lt;- ansC
}
func problemPuller(fileName string) ([]problem, error) {
// read all the problems from the quiz.csv
// 1. open the file
if fObj, err := os.Open(fileName); err == nil {
// 2. we will create new reader
csvR := csv.NewReader(fObj)
// 3. it will need to read the file
if cLines, err := csvR.ReadAll(); err == nil {
// 4. call the parseProblem function
return parseProblem(cLines), nil
} else {
return nil, fmt.Errorf(&quot;error in reading data in csv from %s file; %s&quot;, fileName, err.Error())
}
} else {
return nil, fmt.Errorf(&quot;error in opening the file %s file; %s&quot;, fileName, err.Error())
}
}
func parseProblem(lines [][]string) []problem {
// go over the lines and parse them based on the problem struct
r := make([] problem, len(lines))
for i := 0; i &lt; len(lines); i++ {
r[i] = problem {
question: lines[i][0],
answer: lines[i][1],
}
}
return r
}
type problem struct {
question string
answer   string
}
func exit(msg string) {
fmt.Println(msg)
os.Exit(1)
}

I tried going through each line of code but I am unable to solve it. Can someone please point out what I am doing wrong?

答案1

得分: 2

我可以在Windows上(在“命令提示符”中运行)重现这个问题。但在Linux上没有问题。

以下更改将修复此问题:

  go func() {
- 	fmt.Scanf("%s", &answer)
+ 	fmt.Scanln(&answer)
  	ansC <- answer
  }()

这是一个已知问题,报告为fmt:在Windows和Linux上Scanf的工作方式不同#23562。并且也有一个待处理的修复。不幸的是,这个更改列表有未解决的评论,并且已经被阻塞了很长时间。

英文:

I can reproduce the issue on Windows (running in Command Prompt). But there is not issue on Linux.

The following change will fix the issue:

  go func() {
- 	fmt.Scanf(&quot;%s&quot;, &amp;answer)
+ 	fmt.Scanln(&amp;answer)
  	ansC &lt;- answer
  }()

This is a known issue reported as fmt: Scanf works differently on Windows and Linux #23562. And there is a pending fix for it too. Unfortunately, the CL has unresolved comments and is blocked for a long time.

huangapple
  • 本文由 发表于 2023年5月29日 23:59:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定