我需要保存第一个读取行的值以供循环的下一轮使用。在第二次读取时,我想输出前一个读取行的内容和当前读取行的内容。例如
输入文件:
第 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}
主要区别在于读取部分与排版部分是分离的。首先我读取整个文件,将每一行存储在一个序列中。然后读回该序列以每行排版两个项目。