\if 实际上如何使用?

\if 实际上如何使用?

如果这是新手问题或者重复问题,我深感抱歉,但我已经为此绞尽脑汁很久了,但还是没有成功。:(

我尝试使用 来\if测试空字符串,但没有成功,并将其追溯到我对\if本身的理解。我添加了示例代码,\if以一种非常简单的方式展示了我是如何误用的:

\def\tmpOne{hello}
\tmpOne %shows that \tmpOne produces hello
\if{\tmpOne}{hello}
goodbye %This is never reached.
\fi

更接近我的实际应用的是:

\newcount\tmpInd

\def\funcOne{%
\advance\tmpInd by 1 
\if{\testEmpty{\readHistory{\value\tmpInd}}}{<NOT EMPTY>}
\funcOne
\fi
}   
%where \testEmpty returns either <EMPTY> or <NOT EMPTY>
%and \readHistory is my own previously defined function
%(They work as expected outside of this context)

任何对我明显较弱的理解有帮助的帮助都将不胜感激。:)

编辑:由于其中一条评论中的信息,我添加了一些有关我的特定用例的额外细节......

的定义\testEmpty是:

\newcommand{\testEmpty}[1]{\setbox0=\hbox{#1}\ifdim\wd0=0pt<EMPTY>\else<NOT EMPTY>\fi}

的定义\readHistory是:

\newcommand{\readHistory}[1]{\getdata[#1]\myChangeHistory}

的定义\getData是:

\def\getdata[#1]#2{\csname data:\string#2:#1\endcsname}

数据存储于\storeData

\def\storedata#1#2{\tmpnum=0 \edef\tmp{\string#1}\storedataA#2\end\expandafter\def\csname data:\tmp:0\endcsname{\tmpcnt}}
\def\storedataA#1{\advance\tmpnum by1
\ifx\end#1\else
  \expandafter\def\csname data:\tmp:\the\tmpnum\endcsname{#1}%
  \expandafter\storedataA\fi
}

注意:我通过搜索互联网将它们拼凑在一起,但只理解了部分内容(但它们都实现了我想要的功能)。

答案1

你的代码注定会失败。条件\if测试接下来两个字符代码是否相等不可扩张在其后找到的标记,进行扩展,直到剩下不可扩展的标记。所以

\if{\tmpOne}{hello} goodbye \fi

看到{,它是不可扩展的,然后扩展\tmpOne;在此扩展之后,输入流是

\if{hello}{hello} goodbye \fi

和,因为{h并不是同一个不可展开的标记\if(它们的字符代码不同),所以条件返回 false,TeX 会忽略直到第一个匹配的\else或 的所有内容\fi。没有\else找到,所以剩下的是

\fi

其扩展为空;接下来 TeX 继续。

如果不了解更多信息,\readHistory就不可能提出替代策略。

答案2

我将 egreg 的回答标记为已接受,因为它确实回答了所写的问题。

我最终以稍微不同的方式解决了这个问题,并发布了这个答案,希望它能对其他人有所帮助。

我最终使用了 \newif。

\newif\iftestEmptyBool
\newcommand{\testEmpty}[1]{\setbox0=\hbox{#1}\ifdim\wd0=0pt \testEmptyBooltrue\else \testEmptyBoolfalse\fi}

\newcounter{tmpind}
\setcounter{tmpind}{0}
\def\funcOne{\addtocounter{tmpind}{1}\testEmpty{\readHistory{\thetmpind}}\iftestEmptyBool\else\funcOne\fi}

现在预先运行 \testEmpty,并使用 \iftestEmptyBool 作为条件。

相关内容