为什么我不能将从文件读取的字符串与预定义的字符串进行比较?

为什么我不能将从文件读取的字符串与预定义的字符串进行比较?

我想读取文件中的一行,并借助 将其与预定义宏进行比较\ifx。以下 MWE 显示了我的问题,我原本期望得到Equal,但我得到的是Not Equal

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}

\def\test{latex}

\begin{document}
    \newread\reader%
    \openin\reader=\jobname.txt\relax%
    \readline\reader to \data%
    \closein\reader%
    \ifx\data\test Equal\else Not Equal\fi
\end{document}

答案1

无需额外套餐

更改\catcode\endlinechar从 5-end-of-line 到 9-ignore)并执行\read而不是\readline

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}
\def\test{latex}

\begin{document}
{
    \catcode\endlinechar=9 %
    \newread\reader%
    \openin\reader=\jobname.txt\relax%
    \read\reader to \data%
    \closein\reader%
    \ifx\data\test Equal\else Not Equal\fi
}
\end{document}

在此处输入图片描述

\endlinechar有几种类似的替代方法:如果通过尾随从创建的文件中删除行尾,则可以省略更改的 catcode %

\begin{filecontents*}{\jobname.txt}
latex%
\end{filecontents*}

或者,即使文件不是以 结尾%,也可以省略 catcode 更改,但如果测试字符串末尾添加了空格

\def\test{latex }

这是因为行尾在消化后被音译为空格字符。

readray 答案

readarray包可以将文件读取为\def。然后,我只需要截断尾随空格以准备进行比较。

\documentclass{article}
\usepackage{readarray}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}
\newcommand\removetrailingspaces[1]{\expandafter\rtsaux#1\endrts}
\def\rtsaux#1 \endrts{#1}
\def\test{latex}

\begin{document}
    \readdef{\jobname.txt}\dataraw
    \edef\data{\removetrailingspaces{\dataraw}}
    \ifx\data\test Equal\else Not Equal\fi
\end{document}

另外,也可以定义比较字符串时加上尾随空格,以完全避免截断:

\documentclass{article}
\usepackage{readarray}
\usepackage{filecontents}
\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}
\def\test{latex }

\begin{document}
    \readdef{\jobname.txt}\dataraw
    \ifx\dataraw\test Equal\else Not Equal\fi
\end{document}

答案2

这是一个解决方法LaTeX3

\documentclass{article}

\usepackage{expl3}

\usepackage{filecontents}
\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}

\ExplSyntaxOn
\ior_new:N \l_data_file
\ior_open:Nn \l_data_file {\jobname.txt}
\ior_get:NN \l_data_file \data
\ior_close:N \l_data_file
\ExplSyntaxOff

\def\test{latex}

\begin{document}
    \ifx\data\test Equal\else Not Equal\fi
\end{document}

仅供记录,输出是:

在此处输入图片描述

答案3

有两个问题:

  1. 应该\endlinechar删除
  2. \readline创建一个字符串(catcode 12 个字符,catcode 10 个空格)

因此\test宏应该被“字符串化”;为了删除行尾,还需要一些群体技巧。

\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}

\documentclass{article}

\edef\test{\detokenize{latex}}
\newread\reader%


\begin{document}

\openin\reader=\jobname.txt\relax
\begingroup
\endlinechar=-1
\readline\reader to \temp
\edef\x{\endgroup\def\noexpand\data{\temp}}\x
\closein\reader
\ifx\data\test Equal\else Not Equal\fi

\end{document}

一个更短的解决方案,其中假设辅助文件是一行。

\begin{filecontents*}{\jobname.txt}
latex
\end{filecontents*}

\documentclass{article}
\usepackage{catchfile}

\def\test{latex}

\begin{document}

\CatchFileDef\data{\jobname.txt}{\endlinechar=-1 }
\ifx\data\test Equal\else Not Equal\fi

\end{document}

相关内容