6

I'm having the worst time ever figuring how to get rid of this error I'm getting!

\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}

The table should look like this:

enter image description here

3

The {*} is used as the second argument of multirow to denote the natural width of its contents. For \multicolumn, the second argument is the column type of the multicolumn.

I would suggest using two centred fixed width columns for the first two, \bigstrut to set the height of the first row, and cellspace to add some minimal vertical padding to the other row:

  \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} 

enter image description here

  • Can you explain what "\begin{tabular}{|>{\centering}p{1.8cm}|S{>{\centering}p{1.2cm}}:c|c|}" means? – Erika Olsen Dec 10 '19 at 21:55
  • 1
    p{1.8cm} means the column will have a fixed width of 1.8 cm. These columns are typed in paragraph mode, and they can have line breaks. >{\centering} means that the contents of a cell will be centred in its width (so if the contents requires several lines, the last line is centred). B.t.w., (unrelated) you do not need to load amsmath when you load mathtools: the latter does it for you. – Bernard Dec 10 '19 at 22:02
  • thanks again! with the :c|c| how does it know where the vertical dotted line is supposed to go? – Erika Olsen Dec 10 '19 at 22:28
  • 1
    Between the previous column and the present column (i.e. the first column of type c). There's no ambiguity for the compiler. – Bernard Dec 10 '19 at 22:32
6

TeX error messages can be rather cryptic at times. Sigh.

The * character in

\multicolumn{2}{*}{$\bar{0}_m$}

is not legal. Basically, the second argument of \multicolumn must be a recognized column type, say, l, c, r, or p.


Since all entries in the table are math-y, I would use an array environment, and I'd place this array environment in an unnumbered display-math group, delimited by \[ and \]. This setup allows you to get rid of lots of $ tokens.

By the way, there is absolutely no need for any \multirow or \multicolumn directives.

enter image description here

\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}
  • omg!! I feel so stupid haha. Thank you! – Erika Olsen Dec 10 '19 at 20:51
4

You can avoid multirow and use a much more natural input syntax.

\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}

I define a disposable \threerows command, just inside the math display, which reserves the vertical space of a three row array. For the horizontal spacing, I exploit \mathmakebox of mathtools.

enter image description here

You might want to use \bar{0}_{\mathrlap{n}} in the bottom left entry, to get

enter image description here

  • Thank you! Can you explain what this part means? {\vphantom{\begin{array}{c}\\\\\end{array}}} – Erika Olsen Dec 11 '19 at 2:53
  • 1
    @ErikaOlsen A \vphantom reserves the same vertical space as its argument, but no width. I prefer to define a temporary command (here threerows), so to keep the main code readable. – egreg Dec 11 '19 at 7:24
3

Your problem stems from

\multicolumn{2}{*}{<stuff>}

since \multicolumn expects a column specification in the second argument (and * isn't part of the valid set of options).

Regardless, you can use some details from How to add vertical and horizontal dashed lines in array and tabular enviroments? to replicate what you're after:

enter image description here

\documentclass{article}

\usepackage{array,arydshln}

\begin{document}

\begin{center}
  \renewcommand{\arraystretch}{1.5}%
  \begin{tabular}{ | >{\qquad}c<{\qquad} | >{\quad}c<{\quad} : c | c | }
    \hline
                &             &               &           \\
       $A$      &    $I_m$    & $_m{\bar{0}}$ & $\bar{b}$ \\
                &             &               &           \\
    \hdashline
     $\hat{c}$  & $\hat{0}_m$ &       1       &     $d$   \\
    \hline
    $\hat{0}_n$ & $\hat{0}_m$ &       0       &      0    \\
    \hline
  \end{tabular}
\end{center} 

\end{document}
1

The error message seems so mysterious and (at first glance) unconnected to the source file, so here's a note on reading TeX error messages and the (crude) facilities available to debug something like this.

(TLDR: Add \errorcontextlines=999 and \tracingmacros=1 to your input file, and run TeX with settings max_print_line=10000 and error_line=254 and half_error_line=238, to get more output.)

First, having produced a small example that reproduces the error (as in the question), go further and remove one-by-one all packages and options that don't change the error message. So, starting with the version in the question, you might arrive at something like:

\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}

by removing packages and options to \documentclass. Then after looking at the line number that causes the error (the second row of the table), you can minimize even further, removing the \begin{center} … \end{center}, and all but the second row of the table:

\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}

No extra packages, just core LaTeX! The error message now is something like:

! Missing number, treated as zero.
<to be read again> 
                   *
l.4 ...\bar{c}$} & \multicolumn{2}{*}{$\bar{0}_m$} 
                                                   & 1 & $d$\\
? 

The way error messages are printed in TeX has a certain grammar; in short after the first line (the one starting with !) you should read the lines in pairs. These pairs of lines are TeX's input stack (the things it was reading/expanding) at the time the error was encountered. In each pair of lines, the first line is what TeX had already read (by the time it produced the error) and the second line is what it was not yet read (and therefore irrelevant to the error, but useful for context in recognizing what that pair of lines is). Also the first of each pair of lines starts with what kind of token list it is or where it came from, e.g. the line starting with l.4 means the input came from line 4.

So here, TeX encountered the error after reading the part of line 4 until \multicolumn{2}{*}{$\bar{0}_m$}. Sometimes, knowing this much is enough, but often it is not. In this case, there's no immediately discernible connection between Missing number, treated as zero and the <to be read again> * and the source line. What's going on is that LaTeX, in an attempt to avoid confusing the user, helpfully turns off all but the first and last pair of context lines in the error. To undo this, add something like \setcounter{errorcontextlines}{999} (or simply \errorcontextlines=999) to the top of your file. Then at least you see the full “stack trace”. The output has ...s in it which show that something was truncated, in order to fit within a small width. You can get less truncation by passing in larger values of certain parameters, e.g. instead of pdflatex run max_print_line=10000 error_line=254 half_error_line=238 pdflatex (you can also set those three values in texmf.cnf), to get the error message:

! 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$\\
? 

This finally shows what's going on, and you can also add \tracingmacros=1 and search for the corresponding macros in the log file for more clarity. Basically:

  • TeX said “Missing number, treated as zero” because it saw \@tempcnta * where \@tempcnta is a counter value (and expects a number). So it decided to treat the number as 0, and leave the * to be read later, but is also asking you for confirmation.

  • It saw this \@tempcnta * because it encountered \@tempcnta #2 in the expansion of \@xexpast #1*#2#3#4\@@, which got #2 as *.

  • This comes from the expansion \@expast #1->\@xexpast #1*0x\@@ with #1<-* (this is in the log file)

  • It saw this \@expast * because of \@expast {#1} in the expansion of \@mkpream #1, with #1 being *

  • It saw this \@mkpream * because of \@mkpream {#2} in the expansion of \multicolumn #1#2#3, with #2 being *

  • This came from \multicolumn{2}{*}{$\bar{0}_m$} in the input file.

In other words, the last two points show that the problem is with the second argument of \multicolumn{2}{*}, and hopefully with that clue you can resolve your problem.


The cryptic error message here, which is fair to consider a usability bug, is IMO not TeX's fault but that of LaTeX. I mean, TeX's output undoubtedly has quite a few problems:

  • In addition to “Missing number, treated as zero”, ideally it could have said something more explicit like “you tried to assign the non-integer value * to the counter \@tempcnta

  • It tries to do error-recovery (inserting 0s, $s and what not), which made sense in the days when rerunning TeX would have been very slow, but these days it's better to just show an error message and stop.

  • Its conventions of printing error messages in separate lines, etc., require reading the manual, and aren't intuitive,

  • By default it prints too narrow lines; these days we have much wider screens so the limits don't make sense and the wrapping only confuses.

  • (A fundamental flaw: By providing macro facilities, which do not amount to a proper programming language, it enables their abuse and the creation of monstrosities.)

Nevertheless, the bulk of the problem here is not with TeX itself. If you were a plain TeX user and you knew enough to manually write macros like \newcount\@tempcnta and then sometime later \@tempcnta * (which is what is happening here internally), you'd be in a position to understand and act on the error message as well.

Instead, the bigger problem (IMO) is that LaTeX, which provides so many conveniences to the user, does so in a way that causes an easily (and frequently) shattered illusion of simplicity. Suppressing the error context lines would be justifiable if LaTeX did proper error checking itself: for example, the macro \multicolumn is intended to have the syntax of \multicolumn{NUMBER}{FORMAT}{ITEM}, so it could verify that the second argument is indeed a valid format (or at least that it doesn't contain a *), before passing it to \@mkpream and causing such confusing error messages.

There are historical reasons for this (at the time LaTeX was written there wasn't enough space to do proper error-checking, and these days changing macros may break existing documents so everyone is very wary of changing anything simply for better usability), and some of these lessons seem to have influenced the design of the new LaTeX macro-programming style (expl3) which seems to provide more opportunities for error-checking. Meanwhile with the maturing of LuaTeX, hopefully such macro programming will be less necessary too.

Sorry for a long “answer” that doesn't really help you with your table, but hopefully it helps you or someone make sense of the nonsensical-looking error message and why things are this way, either now or in the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.