Given the following files:



\chapter{Hello, world!}


using System;

class Hello {
    static void Main(string[] args) {
        Console.WriteLine("Hello, world!");

What is the correct syntax to include file C#/hello.cs as a listing in book.tex?

I tried these variants, both fail:

  • \lstinputlisting{C#/hello.cs}
  • \lstinputlisting{C\#/hello.cs}

When I try the first variant, \lstinputlisting{C#/hello.cs}, I get the following error:

! Illegal parameter number in definition of \reserved@a.
<to be read again> 
l.7 \lstinputlisting{C#/hello.cs}

When I try the second variant, \lstinputlisting{C\#/hello.cs}, I get the following error:

! Missing \endcsname inserted.
<to be read again> 
l.7 \lstinputlisting{C\#/hello.cs}

I get the same behavior with (almost) identical error messages in lualatex, pdflatex, and xelatex.

I've tried to find a solution by reading the documetnation of the listings package https://mirror.mwt.me/ctan/macros/latex/contrib/listings/listings.pdf. Alas, in vain.

What is the correct way to use the listings package to include a file that has a #-character in its pathname? (As a workaround, I could of course rename the directory from C# to Csharp, but I'd like to solve the problem, not avoid it.)


2 Answers 2


Unfortunately the author of listings probably didn't account for this case, so there isn't really a "correct" solution.

I think there are two ways, if you insist.

Method 1. Patch \lstinputlisting to allow \#

You could do this...

    \expandafter \endgroup
    \expandafter \oldlstinputlisting
    \expandafter {\detokenize{#1}}%

then do something like...


but one possible disadvantage is that code like \def\filename{myfile.txt}\lstinputlistings{\filename}, which would work before the patch, now wouldn't. (it might break other things as well, I don't know.)

Method 2. Inject a catcode-other # in

Ref. characters - If \@percentchar represents %, is there a macro for #? - TeX - LaTeX Stack Exchange



Use a \hashchar everywhere you want a #.

(this method does implicitly rely on \lstinputlisting "fully expands" the arguments, but this is more likely than not since the primitive \input etc. does for file names. Otherwise putting a catcode-other-token # into the argument itself is possible, but a bit harder)

  • There are \@charlb \@charrb \@backslashchar \space by the way, but you need \makeatletter for the first 3.
    – user202729
    Oct 18, 2022 at 11:47

Method 3: Use \string## instead \#, i.e.:

  • Ah right, I didn't test this one. Although it depends quite a lot on the specific implementation of the macro doing \def once (which converts it to a single #) followed by "full expansion".
    – user202729
    Oct 18, 2022 at 12:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .