\读取重置命令内容

\读取重置命令内容

我需要保存第一个读取行的值以供循环的下一轮使用。在第二次读取时,我想输出前一个读取行的内容和当前读取行的内容。例如

输入文件:
第 1
行 第 2
行 第 3
行 第 4
行 第 5
行 第 6 行

预期输出:
第 1 行/第 2 行
第 3 行/第 4
行第 5 行/第 6 行

以下代码中的 \read 将新命令 \firstline 的内容重置为与当前读取的内容相同

\documentclass[]{article}
\usepackage{ifthen}
\usepackage{filecontents}
\begin{filecontents*}{tmp.txt}
line 1
line 2
line 3
line 4
line 5
line 6
\end{filecontents*}
\newread\reader
\endlinechar=-1
\newcounter{2xLines}
\newcommand\IterateLines{
    \begingroup
        \newcommand{\first}{}
        \setcounter{2xLines}{0}
        \openin\reader=./tmp.txt\relax
        \loop
            \read\reader to \line
            \unless\ifeof\reader
                \stepcounter{2xLines}
                \ifnum\the\value{2xLines}=2
                    \first / \line\par
                    \renewcommand{\first}{}
                    \setcounter{2xLines}{0}
                \else
                    \renewcommand{\first}{\line}
                \fi
        \repeat
        \closein\reader
    \endgroup
}
\makeatother
\begin{document}
\IterateLines
\end{document}

如果格式不正确请见谅——第一篇帖子

答案1

问题在于\renewcommand{\first}{\line}而不是\let\first\line

区别在于前者只是告诉 TeX 用 替换\first\line后者定义\first为具有相同的当前的的意思\line

还有其他一些改进。

\begin{filecontents*}{\jobname.txt}
line 1
line 2
line 3
line 4
line 5
line 6
\end{filecontents*}

\documentclass{article}

\newread\reader
\newcounter{2xLines}

\newcommand\IterateLines{%
  \begingroup
  \endlinechar=-1
  \setcounter{2xLines}{0}%
  \openin\reader=./\jobname.txt\relax
  \loop
  \read\reader to \line
  \unless\ifeof\reader
  \stepcounter{2xLines}
  \ifodd\value{2xLines}
    \let\first=\line
  \else
    \first/\line\par
  \fi
  \repeat
  \closein\reader
  \endgroup
}
\begin{document}

\IterateLines

\end{document}

我以前\jobname只是为了确保不破坏我的文件,这是一个不重要的细节。更重要的是,你应该\endlinechar只在读取文件时设置,而不是全局设置。

此外,使用 可以更轻松地选择偶数或奇数\ifodd。请注意,在这种情况下\value{2xLines}比 更好。\the\value{2xLines}

您可能对使用 的不同实现感兴趣expl3

\begin{filecontents*}{\jobname.txt}
line 1
line 2
line 3
line 4
line 5
line 6
\end{filecontents*}

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\IterateLines{m}
 {
  \egreg_iteratelines:n { #1 }
 }

\seq_new:N \l__egreg_iteratelines_seq
\ior_new:N \g__egreg_iteratelines_stream

\cs_new_protected:Nn \egreg_iteratelines:n
 {
  \seq_clear:N \l__egreg_iteratelines_seq
  \ior_open:Nn \g__egreg_iteratelines_stream { #1 }
  \ior_map_inline:Nn \g__egreg_iteratelines_stream
   {
    \seq_put_right:Nx \l__egreg_iteratelines_seq { \tl_trim_spaces:n { ##1 } }
   }
  \int_step_inline:nnnn { 1 } { 2 } { \seq_count:N \l__egreg_iteratelines_seq }
   {
    \seq_item:Nn \l__egreg_iteratelines_seq { ##1 }
    /
    \seq_item:Nn \l__egreg_iteratelines_seq { ##1 + 1 }
    \par
   }
 }
\ExplSyntaxOff

\begin{document}

\IterateLines{\jobname.txt}

\end{document}

主要区别在于读取部分与排版部分是分离的。首先我读取整个文件,将每一行存储在一个序列中。然后读回该序列以每行排版两个项目。

相关内容