我经历了有史以来最糟糕的时刻,不知道如何摆脱这个错误!
\documentclass[12pt, onecolumn]{article}
\usepackage{multicol, multirow, array}
\usepackage{calc}
\usepackage{colortbl}
\usepackage{geometry}
\usepackage{enumitem}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{arydshln}
\usepackage{booktabs}
\usepackage{bigstrut}
\begin{document}
\begin{center}
\begin{tabular}{|ccc|cc|c|c|}
\hline
\multicolumn{3}{c}{\multirow{2}{*}{$A$}} & \multicolumn{2}{c}{\multirow{2}{*}{$I_m$}} & $_m{\hat{0}}$ & $\hat{b}$\\
\hline
\multicolumn{3}{c}{$\bar{c}$} & \multicolumn{2}{*}{$\bar{0}_m$} & 1 & $d$\\
\hline
\multicolumn{3}{c}{$\bar{0}_n$}&\multicolumn{2}{*}{$\bar{0}_m$}&0&$0$\\
\hline
\end{tabular}
\end{center}
\end{document}
该表应如下所示:
答案1
用作{*}
的第二个参数,multirow
表示其内容的自然宽度。对于\multicolumn
,第二个参数是多列的列类型。
我建议对前两列使用两个居中的固定宽度列\bigstrut
来设置第一行的高度,并cellspace
为另一行添加一些最小的垂直填充:
\documentclass[12pt, onecolumn]{article}
\usepackage{multicol, multirow, array}
\usepackage{calc}
\usepackage{colortbl}
\usepackage{geometry}
\usepackage{enumitem}
\usepackage{mathtools}
\usepackage{fancyhdr}
\usepackage{graphicx}
\usepackage{arydshln}
\usepackage{booktabs, cellspace}
\setlength{\cellspacetoplimit}{5pt}
\setlength{\cellspacebottomlimit}{4pt}
\usepackage{bigstrut}
\begin{document}
\begin{center}
\setlength{\bigstrutjot}{3ex}
\begin{tabular}{|>{\centering}p{1.8cm}|S{>{\centering}p{1.2cm}}:c|c|}
\hline
\bigstrut$A$ & $I_m$ & ${_m{}\hat{0}}$ & $\hat{b}$\\
\hdashline
$\bar{c}$ & $\bar{0}_m$ & 1 & $d$\\
\hline
$\bar{0}_n$ & $\bar{0}_m$ &0&$0$\\
\hline
\end{tabular}
\end{center}
\end{document}
答案2
TeX 错误信息有时可能相当晦涩难懂。唉。
*
中的角色
\multicolumn{2}{*}{$\bar{0}_m$}
是不合法的。基本上,的第二个参数必须是\multicolumn
可识别的列类型,例如l
,,,,或。c
r
p
由于表中的所有条目都是数学,我将使用一个array
环境,并将此array
环境放在未编号的显示数学组中,以\[
和分隔\]
。此设置允许您摆脱大量$
标记。
顺便说一句,完全不需要任何\multirow
或\multicolumn
指令。
\documentclass[12pt]{article}
\usepackage{array} % no other packages needed!
\begin{document}
\[
\renewcommand{\arraystretch}{1.5}
\setlength\arraycolsep{10pt} % default: 5pt
\begin{array}{|*{4}{c|}}
\hline
A & I_m & {}_m\bar{0} & \bar{b} \\
\hline
\hat{c} & \hat{0}_m & 1 & d \\
\hline
\hat{0}_n & \hat{0}_m & 0 & 0 \\
\hline
\end{array}
\]
\end{document}
答案3
您可以避免multirow
并使用更自然的输入语法。
\documentclass[12pt, onecolumn]{article}
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{arydshln}
\begin{document}
\[
\renewcommand{\arraystretch}{1.5}
\newcommand{\threerows}{\vphantom{\begin{array}{c}\\\\\end{array}}}
\begin{array}{|c|c|c:c|}
\hline
\threerows\mathmakebox[4em]{A} & \mathmakebox[2em]{I_m} & {}_m\hat{0} & \hat{b} \\
\hdashline
\bar{c} & \bar{0}_m & 1 & d \\
\hline
\bar{0}_n & \bar{0}_m & 0 & 0 \\
\hline
\end{array}
\]
\end{document}
我在数学显示中定义了一个一次性\threerows
命令,它保留了三行数组的垂直空间。对于水平间距,我利用\mathmakebox
了mathtools
。
你可能想要使用\bar{0}_{\mathrlap{n}}
左下角的条目来获取
答案4
该错误信息似乎非常神秘,并且(乍一看)与源文件无关,因此这里提供了有关阅读 TeX 错误信息以及可用于调试此类问题的(粗略)工具的说明。
(TLDR:将\errorcontextlines=999
和添加\tracingmacros=1
到您的输入文件中,并使用设置max_print_line=10000
和error_line=254
和运行 TeX half_error_line=238
,以获得更多输出。)
首先,制作一个可以重现错误的小示例(如问题所示),然后进一步逐个删除所有不会更改错误消息的包和选项。因此,从版本开始问题,你可能会得到如下结果:
\documentclass{article}
\usepackage{multirow}
\begin{document}
\begin{center}
\begin{tabular}{|ccc|cc|c|c|}
\hline
\multicolumn{3}{c}{\multirow{2}{*}{$A$}} & \multicolumn{2}{c}{\multirow{2}{*}{$I_m$}} & $_m{\hat{0}}$ & $\hat{b}$\\
\hline
\multicolumn{3}{c}{$\bar{c}$} & \multicolumn{2}{*}{$\bar{0}_m$} & 1 & $d$\\
\hline
\multicolumn{3}{c}{$\bar{0}_n$}&\multicolumn{2}{*}{$\bar{0}_m$}&0&$0$\\
\hline
\end{tabular}
\end{center}
\end{document}
通过删除 中的包和选项\documentclass
。然后,在查看导致错误的行号(表格的第二行)后,您可以进一步最小化,删除\begin{center} … \end{center}
以及表格第二行以外的所有内容:
\documentclass{article}
\begin{document}
\begin{tabular}{|ccc|cc|c|c|}
\multicolumn{3}{c}{$\bar{c}$} & \multicolumn{2}{*}{$\bar{0}_m$} & 1 & $d$\\
\end{tabular}
\end{document}
没有额外的软件包,只有核心 LaTeX!现在的错误消息如下:
! Missing number, treated as zero.
<to be read again>
*
l.4 ...\bar{c}$} & \multicolumn{2}{*}{$\bar{0}_m$}
& 1 & $d$\\
?
TeX 中打印错误信息的方式有一定的语法;简而言之,在第一行(以 开头的行!
)之后,您应该成对阅读各行。这些行对是遇到错误时 TeX 的输入堆栈(它正在读取/扩展的内容)。在每一对行中,第一行是 TeX 已经读取的内容(在产生错误时),第二行是尚未读取的内容(因此与错误无关,但对于识别该对行是什么很有用)。此外,每对行的第一行都以它是什么类型的标记列表或它来自哪里开头,例如以 开头的行l.4
表示输入来自第 4 行。
所以在这里,TeX 在读取第 4 行直到 的部分后遇到了错误。有时候,知道这么多就足够了,但通常还不够。在这种情况下,和和源代码行\multicolumn{2}{*}{$\bar{0}_m$}
之间没有立即可辨别的联系 。发生的事情是,LaTeX 为了避免让用户感到困惑,有帮助地关闭了错误中除第一对和最后一对上下文行之外的所有行。要撤消此操作,请在文件顶部添加类似(或简单地)的内容。然后至少你可以看到完整的“堆栈跟踪”。输出中包含 s,表示为了适应较小的宽度,某些内容被截断了。您可以通过传入某些参数的较大值来减少截断,例如而不是run (您也可以在 中设置这三个值),以获取错误消息:Missing number, treated as zero
<to be read again> *
\setcounter{errorcontextlines}{999}
\errorcontextlines=999
...
pdflatex
max_print_line=10000 error_line=254 half_error_line=238 pdflatex
texmf.cnf
! Missing number, treated as zero.
<to be read again>
*
\@xexpast #1*#2#3#4\@@ ->\edef \reserved@a {#1}\@tempcnta #2
\relax \ifnum \@tempcnta >\z@ \@whilenum \@tempcnta >\z@ \do {\edef \reserved@a {\reserved@a #3}\advance \@tempcnta \m@ne }\let \reserved@b \@xexpast \else \let \reserved@b \@xexnoop \fi \exp...
\@mkpream #1->\@firstamptrue \@lastchclass 6 \let \@preamble \@empty \let \protect \@unexpandable@protect \let \@sharp \relax \let \@startpbox \relax \let \@endpbox \relax \@expast {#1}
\expandafter \@tfor \expandafter \@nextchar \expandafter :\expanda...
\multicolumn #1#2#3->\multispan {#1}\begingroup \@mkpream {#2}
\def \@sharp {#3}\set@typeset@protect \let \@startpbox \@@startpbox \let \@endpbox \@@endpbox \@arstrut \@preamble \hbox {}\endgroup \ignorespaces
l.5 \multicolumn{3}{c}{$\bar{c}$} & \multicolumn{2}{*}{$\bar{0}_m$}
& 1 & $d$\\
?
这最终显示了发生了什么,您还可以\tracingmacros=1
在日志文件中添加和搜索相应的宏以获得更清晰的信息。基本上:
TeX 说“缺少数字,视为零”,因为它看到
\@tempcnta *
是\@tempcnta
计数器值(并期望是一个数字)。因此它决定将数字视为 0,并将 留待*
以后读取,但也要求您确认。它看到这一点是
\@tempcnta *
因为它\@tempcnta #2
在的扩展中遇到了\@xexpast #1*#2#3#4\@@
,结果#2
为*
。\@expast #1->\@xexpast #1*0x\@@
这是来自扩展#1<-*
(这是在日志文件中)它之所以看到这一点,
\@expast *
是因为\@expast {#1}
在的扩展中\@mkpream #1
,#1
*
它之所以看到这一点,
\@mkpream *
是因为\@mkpream {#2}
在的扩展中\multicolumn #1#2#3
,#2
*
这来自
\multicolumn{2}{*}{$\bar{0}_m$}
输入文件。
换句话说,最后两点表明问题出在的第二个参数上\multicolumn{2}{*}
,希望通过这个线索您可以解决您的问题。
这里的神秘错误信息,可以视为可用性错误,在我看来,这不是 TeX 的错,而是 LaTeX 的错。我的意思是,TeX 的输出无疑存在不少问题:
除了“缺失数字,视为零”之外,理想情况下还可以说一些更明确的话,例如“您试图将非整数值 * 分配给计数器
\@tempcnta
”它尝试进行错误恢复(插入 0、$s 等等),这在重新运行 TeX 非常慢的时代是有意义的,但现在最好只是显示一条错误消息并停止。
它的惯例是将错误消息打印在单独的行中,等等,需要阅读手册,而且不直观,
默认情况下,它打印的线条太窄;如今我们拥有更宽的屏幕,因此限制没有意义,而包装只会造成混淆。
(一个根本的缺陷:通过提供宏功能,而这不属于适当的编程语言,它会导致它们被滥用并创造出可怕的东西。)
尽管如此,这里的主要问题并不在于 TeX 本身。如果您是普通的 TeX 用户,并且您知道如何手动编写宏,\newcount\@tempcnta
然后过一段时间\@tempcnta *
(这就是内部发生的事情),您也能够理解并处理错误消息。
相反,更大的问题(在我看来)是,LaTeX 为用户提供了如此多的便利,但却以一种容易(且经常)破坏简单的幻觉的方式做到了这一点。如果 LaTeX 本身进行了适当的错误检查,那么抑制错误上下文行是合理的:例如,宏\multicolumn
是故意的具有的语法\multicolumn{NUMBER}{FORMAT}{ITEM}
,因此它可以验证第二个参数确实是有效格式(或者至少它不包含*
),然后再将其传递给\@mkpream
并导致此类令人困惑的错误消息。
这其中有历史原因(在编写 LaTeX 时,没有足够的空间进行适当的错误检查,而如今更改宏可能会破坏现有文档,因此每个人都非常谨慎,不敢仅仅为了提高可用性而更改任何东西),其中一些教训似乎影响了新的 LaTeX 宏编程样式(expl3
)的设计,这似乎提供了更多的错误检查机会。同时,随着 LuaTeX 的成熟,希望这种宏编程也会变得不那么必要。
抱歉,我的“答案”太长了,对你的表格没什么帮助,但希望它能帮助你或其他人理解这个看似毫无意义的错误信息,以及为什么现在或将来会出现这种情况。