使用 c 源中的 #define 值在 .tex 文档中使用

使用 c 源中的 #define 值在 .tex 文档中使用

我想从.h头部(C 语言)提取一个值并将该值用作 LaTeX 的输入。

举个例子,考虑defines.h

#define MEB_COM_PACKET_ID 0x01

.tex在文档表上使用此值main.tex

\begin{table}[ht!]
\begin{tabularx}{0.5\textwidth}{l  X}
    Value & Description \\
    \hline \hline 
    **MEB_COM_PACKET_ID** & balblabla blabla \\
\end{tabularx} 
\end{table}

其中MEB_COM_PACKET_ID将 更新为0x01

答案1

下面的示例使用 C 预处理器以一种格式获取定义的正确值,该格式可以轻松被 LaTeX 读取。

该文件defines_tex.c包含所需的标头,这些标头被\iffalse和包围\fi。预处理器包含标头并传递 TeX 代码,因为 TeX 代码不包含预处理器指令。然后是 TeX 代码,它使用定义作为值来定义所需的宏,例如:

\newcommand*{\MebComPacketId}{MEB_COMP_PACKET_ID}

该 C 文件通过 C 预处理器运行:

gcc -E -P defines_tex.c >defines_tex.tex

启用 shell 转义后,可以从 LaTeX 内部调用 C 预处理器,或者在 LaTeX 运行之前调用它。

生成的TeX文件像往常一样包含在LaTeX中:

\input{defines_tex}

由于将 C 代码包装在\iffalseand中,因此标头 C 代码将被忽略\fi。(C 代码不应意外包含不匹配的 TeX 条件或不匹配的括号。)

完整示例:

\documentclass{article}
\usepackage{filecontents}
\usepackage{booktabs}
\usepackage{tabularx}

\begin{filecontents*}{defines_tex.c}
\iffalse
#include <stdio.h>
#include "defines.h"
\fi
\newcommand*{\MebComPacketId}{MEB_COM_PACKET_ID}
#ifdef MEB_COM_PACKET_NAME
\newcommand*{\MebComPacketName}{MEB_COM_PACKET_NAME}
#else
\newcommand*{\MebComPacketName}{unknown}
#endif
\newcommand*{\SeekCur}{SEEK_CUR}% from stdio.h
\end{filecontents*}
% Call of C preprocessor, when shell escape is enabled
\immediate\write18{gcc -E -P defines_tex.c >defines_tex.tex}
% Load the definition file
\input{defines_tex}

\begin{document}
% Use of the defined values
\begin{tabular}{ll}
  \toprule
  Variable & Value \\
  \midrule
  \verb|MEB_COM_PACKET_ID|   & \MebComPacketId\\
  \verb|MEB_COM_PACKET_NAME| & \MebComPacketName\\
  \verb|SEEK_CUR|            & \SeekCur\\
  \bottomrule
\end{tabular}
\end{document}

结果

答案2

这需要稍微改变\?{MEB_COM_PACKET_ID}表中的语法。

\documentclass{article}
\usepackage{readarray,filecontents,ifthen,tabularx}

\begin{filecontents*}{defines.h}
#define MEB_COM_PACKET_ID 0x01
#define OTHER_ID 0x07
\end{filecontents*}

\newcommand\?[1]{\csname#1\endcsname}
\newcounter{defsindex}
\catcode`#=12 %
\def\ReadTheDefs{%
  \readdef{defines.h}{\Definitions}
  \readArrayij{\Definitions}{Defs}{3}
  \whiledo{\value{defsindex} < \DefsROWS}{
    \stepcounter{defsindex}%
    \def\DEFROW{\arabic{defsindex}}%
    \ifthenelse{\equal{\arrayij{Defs}{\DEFROW}{1}}{#define}}{%
    \expandafter\xdef\csname\arrayij{Defs}{\DEFROW}{2}\endcsname{%
      \arrayij{Defs}{\DEFROW}{3}}}{}%
  }%
}
\catcode`#=6 
\begin{document}
\begin{table}[ht!]
\catcode`#=12 \ReadTheDefs\catcode`#=6 %
\begin{tabularx}{0.5\textwidth}{l  X}
    Value & Description \\
    \hline \hline 
    \?{MEB_COM_PACKET_ID} & balblabla blabla \\
    \hline \hline 
    \?{OTHER_ID} & more stuff \\
\end{tabularx} 
\end{table}
\end{document}

在此处输入图片描述

答案3

您可以使用以下设置从中提取内容defines.h

  1. defines.h捕获宏内部的文件内容(使用catchfile

  2. 使用 TeX 的参数文本定义来提取适当的值。这就像模式识别定义一样,只提取与模式匹配的内容。

下面的例子实现了上述操作:

在此处输入图片描述

\documentclass{article}

\usepackage{catchfile,filecontents}

% Create a dummy defines.h
\begin{filecontents*}{defines.h}
#define MEB_COM_PACKET_ID_NAME abc
#define MEB_COM_PACKET_ID 0x01
#define MEB_COM_PACKET_TYPE def
\end{filecontents*}

\def\extractMEBNAME#1 MEB_COM_PACKET_ID_NAME #2 #3\@nil{#2}
\def\extractMEBID#1 MEB_COM_PACKET_ID #2 #3\@nil{#2}
\def\extractMEBTYPE#1 MEB_COM_PACKET_TYPE #2 #3\@nil{#2}

\begin{document}

\CatchFileDef{\defines}{defines.h}{\catcode`\#=11}% Capture defines.h into \defines (making # act like a regular letter)

\noindent
\begin{tabular}{l l}
    Value & Description \\
    \hline 
    \verb|MEB_COM_PACKET_ID_NAME| & \expandafter\extractMEBNAME\defines\@nil \\% Extract MEB_COM_PACKET_ID_NAME value
    \verb|MEB_COM_PACKET_ID| & \expandafter\extractMEBID\defines\@nil \\% Extract MEB_COM_PACKET_ID value
    \verb|MEB_COM_PACKET_TYPE| & \expandafter\extractMEBTYPE\defines\@nil \\% Extract MEB_COM_PACKET_TYPE value
\end{tabular} 

\end{document}

请注意,如果上面(2)中使用的模式不存在,则会发生错误。

答案4

Werner 和 Steven 的答案的一个变体,假设defines.h只包含以下形式的语句

#define VAR value

并且value不包含@(字符可以改变)。

这是示例文件

% Create a dummy defines.h
\begin{filecontents*}{defines.h}
#define MEB_COM_PACKET_ID_NAME abc
#define MEB_COM_PACKET_ID 0x01
#define MEB_COM_PACKET_TYPE def
\end{filecontents*}

\documentclass{article}

\usepackage{catchfile}

\begingroup
\CatchFileDef{\defines}{defines.h}{\catcode`\#=0 \endlinechar=`@ }
\def\define #1 #2@{\expandafter\gdef\csname#1\endcsname{#2}}
\defines
\endgroup
\newcommand{\?}[1]{%
  \ifcsname#1\endcsname
    \csname#1\endcsname
  \else
    UNDEFINED VAR
  \fi
}

\begin{document}

\begin{tabular}{l l}
Value & Description \\
\hline 
\verb|MEB_COM_PACKET_ID_NAME| & \?{MEB_COM_PACKET_ID_NAME} \\
\verb|MEB_COM_PACKET_ID| & \?{MEB_COM_PACKET_ID} \\
\verb|MEB_COM_PACKET_TYPE| & \?{MEB_COM_PACKET_TYPE} \\
\verb|WHATEVER| & \?{WHATEVER} \\
\end{tabular} 

\end{document}

在此处输入图片描述

相关内容