[Tex/LaTex] Multiple Choice Answer Key in exam package at the end of document

exammacros

I think this is a follow up question to:

Print answer key to multiple choice questions

I am trying to create an answer key at the end of my exam class document where all the questions are multiple choice. Thus, the correct answers are already encoded into the document, as \correctchoice instead of \choice.

What I want it to do is print a simple table at the end of the document with the question number in the first column followed by the letter of the correct answer (as indicated by \correctchoice). I have gotten close, but the only answer stored is the last one.

I have been searching the similar questions, but the problem seems to be in storing the correct choice somewhere, along with the questionlabel and then retrieving it at the end. I am one of those self-taught LaTeXers who cobbles together things I have found elsewhere. This is what I have tried so far. It has two problems, it makes every answer E and it doesn't automatically label the \correctchoice:

\documentclass[answers
]{exam}
\usepackage{forloop}

\makeatletter
\let\xa=\expandafter

\newcounter{numsolns}
\setcounter{numsolns}{0}

\newcommand\solu{%
  %Saves the parameter as a solution
  \stepcounter{numsolns}%
  %\showthe\c@numsolns
  \xa\xdef\csname soln-label-\roman{numsolns}\endcsname{\questionlabel}%
  \xa\long\xa\gdef\csname soln-\roman{numsolns}\endcsname{\thechoice}%
}


%The following is from the exam.sty with one change:
       \def\CorrectChoice{%
         \if@correctchoice
           \endgroup
         \fi
         \ifprintanswers
           % We can't say \choice here, because that would
           % insert an \endgroup:
           \begingroup \@correctchoicetrue
           \CorrectChoice@Emphasis
         \fi
         \item
         \do@choice@pageinfo
                \solu%
       } % CorrectChoice
       \let\correctchoice\CorrectChoice

\makeatother



\begin{document}


\begin{questions}
\question[5] Important Question 1
    \begin{choices}
    \choice 99
    \correctchoice 100 \solu 
    \choice 50
    \choice 1
    \choice none of these
    \end{choices}

\vfill 


    \question[5] Important Question 2.
\begin{choices}
\CorrectChoice 6 \thechoice  \solu
\choice 12
\choice 24
\choice 36
\choice none of these
\end{choices} \answerline \vfill

\end{questions}


\newcounter{loopcounter}
\setcounter{loopcounter}{0}

  \begin{center}
        \ifnum\arabic{numsolns}>0\relax
        \clearpage
        \vspace{1in}
    \begin{tabular}{|c|c|}\hline
    Question & Correct Answer\\\hline
     \forloop{loopcounter}{1}{\value{loopcounter} < \arabic{numsolns}}{%
    \csname soln-label-\romannumeral\value{loopcounter}\endcsname&
                \csname soln-\romannumeral\value{loopcounter}\endcsname \\\hline}
                                \csname soln-label-\romannumeral\arabic{numsolns}\endcsname&
                \csname soln-\romannumeral\arabic{numsolns}\endcsname \\\hline

    \end{tabular}
    \fi
    \end{center}
\end{document}

Thanks to the comments, I have a partially working example.

\documentclass[answers
]{exam}

%%%%The following sets up a box to save all the answer information into.
\newbox\allanswers
\setbox\allanswers=\vbox{}

\newenvironment{answer}
{%
  \global\setbox\allanswers=\vbox\bgroup%
  \unvbox\allanswers%
    \thequestion  \thechoice\\
}%
{%
  \egroup%
}

\newcommand{\showallanswers}{\par\unvbox\allanswers}
%%%%%%%%%%%%%%%%

\makeatletter
\let\xa=\expandafter

%The following is from the exam.sty with one change:
       \newcommand{\CorrectChoice}{%
         \if@correctchoice
           \endgroup
         \fi
         \ifprintanswers
           % We can't say \choice here, because that would
           % insert an \endgroup:
           \begingroup \@correctchoicetrue
           \CorrectChoice@Emphasis
         \fi
         \item
         \do@choice@pageinfo %
       } % CorrectChoice

\makeatother

%%%%%%%%%This interacts with the exam.sty to put the answer in the appropriate spot.
\newcommand{\corchoice}[1]{ \CorrectChoice  #1 \begin{answer}\end{answer} }
\let\oldCorrectChoice\CorrectChoice
\renewcommand{\CorrectChoice}{\oldCorrectChoice \begin{answer}\end{answer} }
\let\correctchoice\CorrectChoice


\begin{document}

\begin{questions}
\question[5] Important Question 1
    \begin{choices}
    \choice 99
    \corchoice{ 100}  
    \choice 50
    \choice 1
    \choice none of these
    \end{choices}

\vfill 


    \question[5] Important Question 2.
\begin{choices}
\corchoice{ 6} 
\choice 12
\choice 24
\choice 36
\choice none of these
\end{choices} \answerline \vfill

\end{questions}

\begin{center}
  Here are the answers:
\end{center}
\showallanswers

\end{document}

There are several issues with this:

  1. I can't seem to change the \newenvironment to a \newcommand and it
    seems wrong to be using \begin{answer}\end{answer} as my way of
    loading the information into the box, but I can live with it.

  2. I can't seem to change the definition of \correctchoice to use the new environment. I have tried hacks like
    \let\oldCorrectChoice\CorrectChoice, but nothing I try seems to
    work. This may be because I am using the exam.sty and I am trying
    to do something impossible.

  3. In the event that (2) is impossible, I would really like to have a
    command that doesn't take extra data as I have now with
    \corchoice{}, but when I try that, the \savebox is eating the \item number.

Best Answer

I started with the first answer to Showing Solutions of the Questions "separately" and modified it to something that is nearly exactly what I wanted. It turns out that \item and \setbox don't play well with each other (read to the bottom of Missing Item number in enumerate for the details).

MWE:

\documentclass[answers]{exam}

%%%%The following sets up a box to save all the answer information into.
\newbox\allanswers
\setbox\allanswers=\vbox{}

\newenvironment{answer}
{%
  \global\setbox\allanswers=\vbox\bgroup %
  \unvbox\allanswers%
    \thequestion \thechoice\\
}%
{%
  \egroup%
}

\newcommand{\CC}{\CorrectChoice \leavevmode\begin{answer}\end{answer}}% New command \CC replaces \CorrectChoice from exam.sty and saves answers in the box \allanswers .


\newcommand{\showallanswers}{%
\ifprintanswers \centering Here are the answers: \par \usebox\allanswers \fi}


\begin{document}


\begin{questions}
\question[5] Important Question 1
    \begin{choices}
    \choice 99
    \CC 100
    \choice 50 
    \choice 1
    \choice none of these
    \end{choices}

% \vfill 


    \question[5] Important Question 2.
\begin{choices}
\CC 6 
\choice 12
\choice 24
\choice 36
\choice none of these
\end{choices} \answerline %\vfill

\end{questions}


\showallanswers
% The answers have the same text format as the answers within the question, so are naturally \textbf when 

\end{document}

The only thing that would make this better is to have the list of problem numbers and answers inside a tabular environment, but I am going to leave that for another day.