提问于:
浏览数:
1950
## 编译环境
操作系统
* [x] Windows 10
* [ ] macOS
* [ ] Linux
`若需勾选,请把[ ]改成[x]`
Tex发行版
* [x] TexLive `2020`
* [ ] MikTeX `版本号`
* [ ] CTeX
`若需勾选,请把[ ]改成[x]`
## 我的问题
需求是这样的,前面使用 csv 排版很多试题(50道选择题+判断题),然后在最后一页用一个表格输出答案。一开始想着在前面拼接一个命令,比如 `\ansfornow`,每遇到一个答案就把它拼进去,但是因为表格中存在 & 和换行符,会报错,所以又想用一个数组或者列表之类的东西把它存起来,后面在表格中用一个循环,从数组中读取答案,把它们放进表格当中,但是这里不太会,也没搜到什么。
后来找到一个办法,用 `csname` 创建很多的命令,代码如下:
```
\newcommand{\saveToAns}[2]{\expandafter\newcommand\expandafter{\csname theAnswer-#1\endcsname}{#2}}
\newcommand{\useAnAns}[1]{\csname theAnswer-#1\endcsname}
```
但是在使用 `multido` 做循环的时候,发现输出不了:
```
\documentclass{ctexart}
\usepackage{multido}
\newcommand{\saveToAns}[2]{\expandafter\newcommand\csname theAnswer-#1\endcsname{#2}}
\newcommand{\useAnAns}[1]{\csname theAnswer-#1\endcsname}
\begin{document}
\multido{\i=1+1,\n=1+3}{5}{\saveToAns{\i}{s}}
\multido{}{10}{\TeX\ }
123
\multido{\i=1+1}{5}{\useAnAns{\i}}
\saveToAns{99}{a}
\useAnAns{99}
\useAnAns{1}
\end{document}
```
![](https://wenda.latexstudio.net/data/attach/210125/jxduRASw.png)
直接使用明文写 `\saveToAns{99}{a}` 和 `\useAnAns{99}` 是可以输出的,但是用 `\multido` 的都输出不了,麻烦帮我看看是什么问题导致的,或者有更好的实现方式吗?
2 回答
16
你应该是想要这样的效果吧?
```
\documentclass{ctexart}
\usepackage{expl3,enumitem,etoolbox,array}
\ExplSyntaxOn
\cs_new_eq:NN \Repeat \prg_replicate:nn
\ExplSyntaxOff
\newcounter{question}
\newcommand{\question}[1]{
\stepcounter{question}
\global\csdef{questiontext\thequestion}{#1}
\begin{enumerate}[label=\thequestion]
\item #1
\end{enumerate}
}
\newcounter{answer}
\newcommand{\answer}[1]{
\stepcounter{answer}
\global\csdef{answertext\theanswer}{#1}
}
\newcounter{answertmp}
\newcommand{\answertext}{
\csuse{answertext\theanswertmp}
\stepcounter{answertmp}
}
\newcommand{\answertable}{
\newpage
\setcounter{answer}{1}
\setcounter{answertmp}{1}
\begin{table}[h]
\begin{tabular}{|c|*{10}{p{2em}<{\centering}|}}
\hline
\Repeat{2}{
题号\Repeat{10}{&\theanswer\stepcounter{answer}}\\\hline
答案\Repeat{10}{&\answertext}\\\hline
}
\end{tabular}
\end{table}
}
\begin{document}
\question{选择题第一题}\answer{A}
\question{选择题第二题}\answer{B}
\question{选择题第三题}\answer{D}
\question{选择题第四题}\answer{A}
\question{选择题第五题}\answer{D}
\question{选择题第六题}\answer{C}
\question{选择题第七题}\answer{B}
\question{选择题第八题}\answer{B}
\question{选择题第九题}\answer{C}
\question{选择题第十题}\answer{B}
\question{判断题第一题}\answer{T}
\question{判断题第二题}\answer{T}
\question{判断题第三题}\answer{F}
\question{判断题第四题}\answer{T}
\question{判断题第五题}\answer{F}
\question{判断题第六题}\answer{F}
\question{判断题第七题}\answer{F}
\question{判断题第八题}\answer{F}
\question{判断题第九题}\answer{T}
\question{判断题第十题}\answer{F}
\answertable
\end{document}
```
-
回复 nygNsEsvQdp7 :嗯嗯 – 木头 2021-01-26 17:58 回复
-
回复 木头 : 现在解决了,把 `\csdef` 换成了 `\csedef` – nygNsEsvQdp7 2021-01-26 15:30 回复
-
回复 木头 :多带带使用没有问题,但是使用 CSV 循环的时候还是出问题了,麻烦看一下 – nygNsEsvQdp7 2021-01-26 14:21 回复
-
回复 nygNsEsvQdp7 :不客气[旺柴] – 木头 2021-01-26 13:41 回复
-
是的,就是这样的效果,非常感谢! – nygNsEsvQdp7 2021-01-26 13:00 回复
0
我的完整用法类似于这样:
```
\documentclass{ctexart}
\usepackage{expl3,enumitem,etoolbox,array}
\ExplSyntaxOn
\cs_new_eq:NN \Repeat \prg_replicate:nn
\ExplSyntaxOff
\usepackage{datatool}
\newcounter{question}
\newcommand{\question}[1]{
\stepcounter{question}
\global\csdef{questiontext\thequestion}{#1}
\begin{enumerate}[label=\thequestion]
\item #1
\end{enumerate}
}
\begin{document}
\newcommand{\slpath}{csv/1-选择.csv}
\group{选择题}{(每题2分)}
\DTLloaddb{selects}{\slpath}
% \DTLdisplaylongdb{selects}
\begin{questions}[p]
\DTLforeach*{selects}{%
\curquestiontext=题目,\anstextA=答案A,\anstextB=答案B,\anstextC=答案C,\anstextD=答案D,\correctAnswer=正确答案}{%
%\ifthenelse{\DTLcurrentindex=30}{\dtlbreak}{}%
\question{\curquestiontext{}}
\fourchoices{\anstextA}{\anstextB}{\anstextC}{\anstextD}
\addToAnswer{\noexpand\correctAnswer}%
}
\end{document}
```
因为有选择判断和问答,最后出来的答案里面全是最后一个问答题的答案,也就是说 `\correctAnswer` 在循环的过程中没有展开,这个怎么办啊?
-
因为我的选择题和判断题总数是50,具体每个数量多少是不确定的,而它们又在不同的CSV中,所以又不好去再使用 DTLforeach 循环一次输出答案,只能把50个答案存起来最后一起输出 – nygNsEsvQdp7 2021-01-26 14:53 回复
你的回答
请登录后回答
你的回答将会帮助更多人,请务必认真回答问题。