von Gast » Do 13. Apr 2017, 07:47
Praktisch sämtliche Funktionen von
xstring sind nicht voll expandierbar. Das bedeutet, dass \ifcase da keine Zahl zu sehen bekommt, sondern eine Abfolge von Makros, deren Ausgabe dann erst im Output die gewünschte Zeichen ergibt.
In Deinem Fall könntest Du einfach das erste Token aus der ersten Expansion von \MCa etc. abschneiden:
\documentclass[parskip=half]{scrartcl}
\usepackage{xstring}
\makeatletter
\newcommand*{\firsttokof}[1]{%
\expandafter\@firsttokof #1\@nil
}
\newcommand*{\@firsttokof}{}
\def\@firsttokof#1#2\@nil{#1}
\makeatother
\begin{document}
\newcommand{\MCa}{0Diese erste Antwort a) ist falsch}
\newcommand{\MCb}{1Diese zweite Antwort b) ist richtig}
Falsch (0) / Wahr (1): \StrLeft{\MCa}{1} \\ % Ergibt korrekterweise 0
Falsch (0) / Wahr (1): \StrLeft{\MCb}{1} \\ % Ergibt korrekterweise 1
\ifcase 0 % Funktioniert für 0 bzw. 1 wie beabsichtigt
FALSCH: \StrGobbleLeft{\MCa}{1}
\or
RICHTIG: \StrGobbleLeft{\MCa}{1}
\fi
\expandafter\ifcase \firsttokof{\MCa}% Ergibt keinen Fehler =Missing number, treated as zero.=
FALSCH: \StrGobbleLeft{\MCa}{1}
\or
RICHTIG: \StrGobbleLeft{\MCa}{1}
\fi
\ifcase 1% Funktioniert für 0 bzw. 1 wie beabsichtigt
FALSCH: \StrGobbleLeft{\MCb}{1}
\or
RICHTIG: \StrGobbleLeft{\MCb}{1}
\fi
\expandafter\ifcase \firsttokof{\MCb}% Ergibt keinen Fehler =Missing number, treated as zero.=
FALSCH: \StrGobbleLeft{\MCb}{1}
\or
RICHTIG: \StrGobbleLeft{\MCb}{1}
\fi
\end{document}
Ohne das \expandafter in der Definition würde \ifcase das gesamte \MCa zu sehen bekommen. Das wäre zwar für die Entscheidung noch korrekt, würde dann aber im Fall von \MCa den Rest des Strings ausgeben.
In
l3kernel sind übrigens weitergehende Funktionen zum Zerlegen von Tokenlisten und Strings enthalten. Wenn du also derartige Dingen machen willst, könnte es sinnvoll sein, sich damit näher zu beschäftigen.
Praktisch sämtliche Funktionen von [p]xstring[/p] sind nicht voll expandierbar. Das bedeutet, dass [tt]\ifcase[/tt] da keine Zahl zu sehen bekommt, sondern eine Abfolge von Makros, deren Ausgabe dann erst im Output die gewünschte Zeichen ergibt.
In Deinem Fall könntest Du einfach das erste Token aus der ersten Expansion von [tt]\MCa[/tt] etc. abschneiden: [code]\documentclass[parskip=half]{scrartcl}
\usepackage{xstring}
\makeatletter
\newcommand*{\firsttokof}[1]{%
\expandafter\@firsttokof #1\@nil
}
\newcommand*{\@firsttokof}{}
\def\@firsttokof#1#2\@nil{#1}
\makeatother
\begin{document}
\newcommand{\MCa}{0Diese erste Antwort a) ist falsch}
\newcommand{\MCb}{1Diese zweite Antwort b) ist richtig}
Falsch (0) / Wahr (1): \StrLeft{\MCa}{1} \\ % Ergibt korrekterweise 0
Falsch (0) / Wahr (1): \StrLeft{\MCb}{1} \\ % Ergibt korrekterweise 1
\ifcase 0 % Funktioniert für 0 bzw. 1 wie beabsichtigt
FALSCH: \StrGobbleLeft{\MCa}{1}
\or
RICHTIG: \StrGobbleLeft{\MCa}{1}
\fi
\expandafter\ifcase \firsttokof{\MCa}% Ergibt keinen Fehler =Missing number, treated as zero.=
FALSCH: \StrGobbleLeft{\MCa}{1}
\or
RICHTIG: \StrGobbleLeft{\MCa}{1}
\fi
\ifcase 1% Funktioniert für 0 bzw. 1 wie beabsichtigt
FALSCH: \StrGobbleLeft{\MCb}{1}
\or
RICHTIG: \StrGobbleLeft{\MCb}{1}
\fi
\expandafter\ifcase \firsttokof{\MCb}% Ergibt keinen Fehler =Missing number, treated as zero.=
FALSCH: \StrGobbleLeft{\MCb}{1}
\or
RICHTIG: \StrGobbleLeft{\MCb}{1}
\fi
\end{document}[/code]
Ohne das [tt]\expandafter[/tt] in der Definition würde [tt]\ifcase[/tt] das gesamte [tt]\MCa[/tt] zu sehen bekommen. Das wäre zwar für die Entscheidung noch korrekt, würde dann aber im Fall von [tt]\MCa[/tt] den Rest des Strings ausgeben.
In [p]l3kernel[/p] sind übrigens weitergehende Funktionen zum Zerlegen von Tokenlisten und Strings enthalten. Wenn du also derartige Dingen machen willst, könnte es sinnvoll sein, sich damit näher zu beschäftigen.