当不应该有输入时提示 \read 输入

当不应该有输入时提示 \read 输入

我不明白\read# to \sth它们\ifeof应该如何工作。如果使用不在 [0,15] 中的流,或者流已关闭或不存在,它会提示您手动输入数字(如果您在控制台中运行 .tex)。否则,您会收到错误,并且它会当场破坏文档,在我的情况下 - 不会打印出 longtable 的其余部分。

MWE 模拟了这种情况。数据从文件中读取,每次 2 行,有开始日期和结束日期。在原始版本中,这些会与当前日期行的日期进行比较,如果匹配,则开始读取\immediate\write数据文件,直到第 2 个日期匹配,然后停止,关闭输出流,并且每对日期都会发生这种情况 - 这里应该是简单的覆盖,\aaaaa and \bbbbb因为这足以重现错误。

原始代码中有几个地方包含\ifeof,好像我永远无法让它转到真正的分支。在 MWE 中,T 分支也不会执行。

梅威瑟:

\documentclass[a4paper]{article}
\usepackage{
    etoolbox,
    xstring,
}
\newcounter{foo}
\newbool{hasReadPeriod}

\begin{document}

\newwrite\periods
\immediate\openout\periods=1.dat
\def\mynum{6}
\def\testi{%
    \stepcounter{foo}%
    \immediate\write\periods{0000-00-\thefoo}%
    \ifnum\thefoo=\mynum
    \else
        \testi{}%
    \fi
}

\testi{} Test 1: write \mynum{} rows + 1 empty.\par \vspace*{0.25cm}\hrule\vspace*{0.25cm}
\immediate\closeout\periods


\newread\periods
\openin\periods=1.dat
\setcounter{foo}{0}


Test 2: step counter foo, read 2 rows from file on odd numbers
\def\testii{%
    \stepcounter{foo}%
    \thefoo%
    \ifeof\periods
        this never shows up, why?
        \closein\periods% does nothing
    \else
        \ifbool{hasReadPeriod}%
            {%  
                . F\quad%
                \global\boolfalse{hasReadPeriod}%
                b5 = \bbbbb%
            }%
            {%
                \global\read\periods to \aaaaa%
                \global\read\periods to \bbbbb%
                \global\booltrue{hasReadPeriod}%
                . T\quad%
                a5 = \aaaaa%
            }%
    \fi
    %
    \ifnum\thefoo=\mynum
        \quad LAST ROW%
    \fi
    %
    \par
}

\testii{}\testii{}\testii{}
\testii{}\testii{}\testii{}
% \testii{}% COMMENT ME OUT OR WON'T BUILD (WO/ MAN. INPUT)
\end{document}

编辑:\global是因为 main 中的相应内容不会被读取或写入,或 T/F'd,它位于 longtable 中。不知道这在示例中有多重要,但考虑到它位于命令中,我宁愿确定一下。

答案1

如果你使用

                \global\read\periods to \aaaaa%
\show\aaaaa

然后你会在终端上看到

> \aaaaa=macro:
->0000-00-3 .
<argument> ...ead \periods to \aaaaa \show \aaaaa 
                                                  \global \read \periods to ...
l.65 \testii{}\testii{}\testii
                              {}
? 
> \aaaaa=macro:
->0000-00-5 .
<argument> ...ead \periods to \aaaaa \show \aaaaa 
                                                  \global \read \periods to ...
l.66 \testii{}\testii
                     {}\testii{}
? 
> \aaaaa=macro:
->\par .

因此,最后一行\aaaaa\par,但是你做了两个\read,所以走到最后。

因此你可以测试一下:

\documentclass[a4paper]{article}

\usepackage{
    etoolbox,
    xstring,
}

\newcounter{foo}
\newbool{hasReadPeriod}

\begin{document}

\newwrite\periods
\immediate\openout\periods=1.dat
\def\mynum{6}
\def\testi{%
    \stepcounter{foo}%
    \immediate\write\periods{0000-00-\thefoo}%
    \ifnum\thefoo=\mynum
    \else
        \testi{}%
    \fi
}

\testi{} Test 1: write \mynum{} rows + 1 empty.\par \vspace*{0.25cm}\hrule\vspace*{0.25cm}
\immediate\closeout\periods


\newread\periods
\openin\periods=1.dat
\setcounter{foo}{0}

\def\endpar{\par}
Test 2: step counter foo, read 2 rows from file on odd numbers
\def\testii{%
    \stepcounter{foo}%
    \thefoo%
    \ifeof\periods
        this never shows up, why?
        \closein\periods% does nothing
    \else
        \ifbool{hasReadPeriod}%
            {%  
                . F\quad%
                \global\boolfalse{hasReadPeriod}%  why all the \global????
                b5 = \bbbbb%
            }%
            {%
                \global\read\periods to \aaaaa%
\ifx\aaaaa\endpar\else
                \global\read\periods to \bbbbb%
                \global\booltrue{hasReadPeriod}%
                . T\quad%
                a5 = \aaaaa%
\fi
            }%
    \fi
    %
    \ifnum\thefoo=\mynum
        \quad LAST ROW%
    \fi
    %
    \par
}

\testii{}\testii{}\testii{}
\testii{}\testii{}\testii{}
\testii{}% COMMENT ME OUT OR WON'T BUILD (WO/ MAN. INPUT)
\end{document}

相关内容