Löschen einer Leerzeile im Quellcode, die unerwartete Funktionen verursacht [closed]

38

Schreiben Sie ein Skript, das einwandfrei funktioniert, wenn im Ablauf der Programmlogik eine leere Zeile vorhanden ist, diese jedoch abbricht oder ein unerwartetes Verhalten verursacht, wenn diese Zeile entfernt wird.

Vermeiden Sie Standardlücken und dumme Antworten. Ihr Programm sollte etwas "Nützliches" tun, auch wenn es nur ein paar Ganzzahlen hinzufügt.

Das Entfernen einer leeren Zeile aus einer mehrzeiligen Zeichenfolge zählt nicht, es sei denn, die erwartete Ausgabe dieser mehrzeiligen Zeichenfolge sollte sich technisch nicht ändern (dh, wenn Sie alle übereinstimmenden leeren Zeilen entfernen ^$).

Whitespace-Dummheiten sind ebenfalls nicht erlaubt. Mach keine seltsamen Dinge mit Wagenrückläufen, Tabulatoren, Leerzeichen usw.

Naftuli Kay
quelle
11
Ich denke, Sie sollten Whitespace ausschließen.
Nneonneo
17
Ich denke , dass Whitespace ist ein „ Standard - Schlupfloch
core1024
5
nneonneo spricht von Whitespace , einer Sprache, die nur Leerzeichen als Syntax verwendet.
Kyle Kanos
4
"Unerwartete Funktionalität" ist ein sehr guter Ausdruck.
Kaz
3
Ich stimme dafür, diese Frage als "Off-Topic" zu schließen, da hinterhältige Herausforderungen auf dieser Site nicht mehr zum Thema gehören. meta.codegolf.stackexchange.com/a/8326/20469
cat

Antworten:

62

Javascript

Öffnet ein Benachrichtigungs-Popup mit "Hallo, Welt!" Wenn die leere Zeile vorhanden ist, wird andernfalls "0" gemeldet.

(function(){
    alert(~(arguments.callee+[]).indexOf('\n\n') && "Hello, World!");

})();

Demo

Erläuterung:

arguments.callee ist ein Verweis auf die sich selbst ausführende anonyme Funktion.

Durch Anhängen eines leeren Arrays ( []) wird die Funktion in eine Zeichenfolge umgewandelt, die den Quellcode angibt.

indexOfGibt zurück, -1wenn die Zeichenfolge nicht gefunden wird.

Durchführen einer bitweisen Operation nicht ( ~) ergibt -1in schaltet wird 0, der ein Falsey Wert.

nderscore
quelle
2
Was für ein Trick ist das ?!
Kroltan
1
arguments.calleeenthält die Quelle der Funktion.
Matthew
2
Beachten Sie, dass dies nicht mehr im strikten Modus funktioniert (den der modernste Code verwenden würde). Strenger Modus verbietet die Verwendung von arguments.callee.
Daniel Lo Nigro
1
@Michael: Nein, spec sagt nichts über das genaue Format aus. Tatsächlich gibt es herumlaufende Motoren, die keine Leerzeichen enthalten.
Bergi
2
@DanielLoNigro Sie können dem Funktionsausdruck einfach einen Namen geben und diesen anstelle von verwenden arguments.callee. Auch macht es kürzer.
eine Katze
42

C

Dieses magische 8-Ball-Programm funktioniert weiterhin ohne die Leerzeile, ist jedoch etwas entscheidender - keine der neutralen Antworten wird jemals in der Ausgabe erscheinen.

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main() {
  int x, t;
  char *quotes[] = {
        // Positive :-)
        "It is certain", "It is decidedly so", "Without a doubt", "Yes definitely", "You may rely on it",
        "As I see it, yes", "Most likely", "Outlook good", "Yes", "Signs point to yes",
        // Indifferent :-\

        "Reply hazy try again", "Ask again later", "Better not tell you now", "Cannot predict now", "Concentrate and ask again",
        // Negative :-(
        "Don't count on it", "My reply is no", "My sources say no", "Outlook not so good", "Very doubtful" };
  srandom(time(NULL)); // Initialize random number generator
  x = random() % (sizeof(quotes) / sizeof(char*)); // Choose a random outcome
  printf("The Magic Eight Ball says...\n%s\n",quotes[x]);
  return 0;
}

Erläuterung

Wenn der C-Parser einen umgekehrten Schrägstrich gefolgt von einem Zeilenumbruchzeichen sieht, ignoriert er beide und behandelt die zweite Zeile als Fortsetzung der ersten. Ohne die leere Zeile werden alle "gleichgültigen" Antworten als Teil des vorherigen Kommentars behandelt.

zimperliches Ossifrage
quelle
51
Ich habe +1 gegeben, aber wenn C-Kommentare mit einem Backslash enden, wird dies zu einer Standardlücke, IMO.
Tim S.
2
Es war ein Verweis auf diesen "Standard-Schlupfloch" -Posten , also möglicherweise nicht wörtlich eine "Lücke".
Tim S.
5
@TimS. Wenn Ihnen diese "Lösung" langweilig ist, warum haben Sie dann abgestimmt?
John Dvorak
8
Die Backslash-the-next-Line-in-a-Comment-Antworten (Trigraph oder kein Trigraph) lassen mich wünschen, ich hätte 125 Ruf. Ich sehe sie immer wieder und sie beginnen sich schrecklich zu wiederholen, sind durchsichtig und nicht mehr schlau oder lustig. (Was für diejenigen, die sie benutzen, bedauerlich ist, wie zimperlich hier, weil sie in keiner Weise den Zorn verdienen und sich dessen manchmal überhaupt nicht bewusst sind - aber der Trick verdient es.)
doppelgreener
4
@Jan Standard zu werden beginnt nicht die gleichen wie langer Standard / verbraten ist ... ist die Verwendung ziemlich hier klug, es nicht aussehen fehl am Platz ( im Gegensatz zu einigen Ich habe gesehen , welche aus unerklärlichen Gründen Charakter (s hat) bei das Ende eines Kommentars oder dessen Kommentare mit dem / den Kommentar-Startzeichen (n) beenden, um etwas Ungewöhnliches zu tun). Also: Ich stimme der Lösung zu, nicht der weiteren Anwendung ihres Tricks.
Tim S.
37

Befunge-93

v
&
&
+
#

.
@

Mein erstes befunge Programm :)

Es liest zwei Zahlen aus der Eingabe und gibt ihre Summe aus. Wenn Sie die leere Zeile löschen, wird nichts gedruckt.

Erläuterung:

vSetzt eine Abwärtsrichtung zum Ausführen des Codes
&liest eine Ganzzahl
+addiert die Zahlen
#überspringt den nächsten Befehl
.druckt eine Ganzzahl vom Stapel und
@beendet das Programm

#Überspringt wie geschrieben die leere Zeile und setzt mit fort .. Kaufen, wenn Sie die leere Zeile löschen, .wird übersprungen.

Es scheint einen netten Dolmetscher bei http://befunge.aurlien.net/ zu geben

aditsu
quelle
Ah, kluger.
Siehe auch
1
Befunge 98 macht das auch. Guter Einfall. Und dieser Dolmetscher hat einige Vorteile (ich habe Ihren nicht viel genutzt, deshalb kenne ich seine Vorteile nicht).
Justin
32

Ruby / Shell

​​​​​​
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!   The Amazing Integer Adder             !
#! Adds 1 and 1, and displays the result   !
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

p 1+1

Funktioniert einwandfrei, wenn sich eine neue Zeile oben befindet, andernfalls wird die erste Kommentarzeile von der Shell als fehlerhafter Shebang interpretiert.

Histokrat
quelle
3
Würde das nicht immer funktionieren oder immer nicht? Wenn Sie es zum Beispiel ruby youranswer.rbso laufen lassen, würde es nicht nach einem Shebang suchen, weil es bereits im Ruby-Interpreter ausgeführt wird, aber wenn Sie es so ./youranswer.rblaufen lassen, würde es überhaupt nicht ausgeführt werden, weil es keinen Shebang gibt.
Setzen Sie Monica
6
Zumindest bei meinem Ruby wird der Shebang gewürdigt, auch wenn Sie ihn als ausführen. Dies ruby youranswer.rbkann nützlich sein, um die erforderlichen Befehlszeilenoptionen in der Datei festzulegen. Also ohne den Zeilenvorschub bekomme ichruby: no Ruby script found in input (LoadError)
Histokrat 13.06.14
29

Scala

case class IntWrapper(i: Int)

{
  val answer = (IntWrapper(0) /: (1 to 100)){(x, y) => IntWrapper(x.i + y)} // Add up ints
  println(s"Sum of wrapped integers is $answer")
}

Wenn Sie die leere Zeile entfernen, wird keine Ausgabe gedruckt. Welches ist für das Beste, da Ihr Stapel überlaufen würde, wenn Sie tatsächlich aufriefen IntWrapper.

Dies ist ein Eckfall von Scalas Semikolon-Inferenz. Normalerweise erhalten Zeilenumbrüche ein Semikolon, wenn der resultierende Code gültig ist. Die Scala-Entwickler wollten die Benutzer jedoch nicht dazu zwingen, ägyptische Klammern zu verwenden. Daher ist es zulässig, die Klammern für eine Klassendefinition unmittelbar danach in die Zeile einzufügen - es wird kein Semikolon hinzugefügt, auch wenn dies möglich ist. Eine leere Zeile trennt jedoch die Klammern von der Klassendefinition. Wenn die leere Zeile entfernt ist, ändert sich der Code von einer Klassendefinition und einem Block zu einer Klassendefinition mit einem Konstruktor - und zwar einem rekursiven Konstruktor!

James_pic
quelle
6
Sehr nett von ihnen, ägyptische Klammern nicht zu zwingen. Aber die Semikolon-Schlussfolgerung ist meiner Meinung nach eine schlechte Idee.
Almo
Semikolon-Inferenz erhält einen schlechten Ruf, hauptsächlich aufgrund von JavaScript. Es ist ein bisschen weniger schmerzhaft, wenn Sie die Sprache so gestalten, dass sie im Vordergrund steht (niemand beschwert sich zum Beispiel in Python darüber). Leider enthielt Scala einige Funktionen, die mit Semikolon-Inferenz nicht gut zu tun haben. Es gibt diese und Postfix-Operatoren (die ich in meiner Antwort verwenden wollte, aber es ist ein bisschen passé).
James_pic
2
@James_pic: AFAIK niemand beschwert sich darüber in Python, weil es in Python nicht existiert. In JS sind Semikolons ein notwendiger Bestandteil der Syntax und können an bestimmten Stellen eingefügt (abgeleitet) werden. In Python sind Semikolons kein notwendiger Bestandteil der Syntax, sondern können optional verwendet werden. Das ist ein großer Unterschied.
Mason Wheeler
Es scheint ein großer Unterschied zu sein, aber wenn Scala einige Features entfernt, die derzeit zu mehrdeutigen Anweisungsgrenzen führen, würde dies von JavaScript auf Pythons Seite übergehen.
James_pic
1
@James_pic: Das Besondere an Python ist, dass dort in Zeilenumbrüchen die Anweisung beendet wird, es sei denn, es wurde ein Escapezeichen gesetzt oder es befindet sich in einer beliebigen eckigen Klammer. Das heißt, es gibt keine vollständige / unvollständige Regel.
Jan Hudec
27

GolfScript

~{.@\%:

}do;

Berechnet die GCD von zwei Ganzzahlen ungleich Null. Das Entfernen der leeren Zeile unterbricht das Programm.

Probieren Sie es online aus.

Wie es funktioniert

Dies ist eine GolfScript-Implementierung des Euklidischen Algorithmus:

      # STACK: "15 24"
~     # Interpret the input string.
{     # STACK: 15 24
  .@  # Duplicate the topmost integer and rotate the other on top of both copies.
      # STACK: 24 24 15
  \   # Swap the topmost integers.
      # STACK: 24 15 24
  %   # Calculate the modulus.
      # STACK: 24 15
}do   # If the modulus is non-zero, repeat the loop.
;     # Discard the last modulus.

Es gibt nur ein kleines Problem:

{}doLöst den Modul aus dem Stapel, um zu überprüfen, ob er wahr ist. Er muss daher am Ende der Schleife dupliziert werden. Dies wird normalerweise von ausgeführt ., :\n\nhat jedoch den gleichen Effekt: Es speichert das oberste Stapelelement in der Variablen LF ( :\n) und überträgt dann den Inhalt dieser Variablen.

Dennis
quelle
7
Wow, auch das ist eine Variable? : O
aditsu
@aditsu: Nur #, {und }kann nicht als Variablennamen verwendet werden, da sie von der Syntax ist Teil. Jedes andere Token ist in Ordnung, einschließlich Zeichenfolgen.
Dennis
@ Tennis wow. Bis sogar Zeichenfolgen können als Variablen verwendet werden. Ist das für irgendetwas nützlich?
John Dvorak
@JanDvorak: Abgesehen von einigen Randfällen (palindromischer Code, hinterhältiger Code , wahrscheinlich nicht. Ich denke, dies ist nur ein ( dokumentierter ) Nebeneffekt davon, wie der GolfScript-Interpreter den Code in Token aufteilt.
Dennis,
@Dennis bedeutet das, dass .:-1die Eingabe in gespeichert wird -1, nicht das Minuszeichen selbst? Hmm ...
John Dvorak
23

MediaWiki-Vorlagensyntax

Vorlage definieren: Foo als

{{{a

b|Uh-oh!}}}

Auf einer anderen Seite

{{Foo|a

b=Works!}}  <!-- outputs "Works!" -->

{{Foo|a


b=Works!}}  <!-- outputs "Uh-oh!" -->

{{Foo|a
b=Works!}}  <!-- outputs "Uh-oh!" -->

In MediaWiki können Parameternamen Zeilenumbrüche enthalten.

Ypnypn
quelle
1
Schön, das entspricht genau dem, wonach ich gesucht habe, seltsame Randfälle wie dieses.
Naftuli Kay
16

LaTeX (backref)

Der folgende LaTeX-Code verwendet ein Zitat und das Zitat enthält eine Liste von Seiten, auf denen der Eintrag zitiert wird. Hier ist es die erste Seite. Das Paket hyperreffügt auch PDF-Links hinzu, die Referenz auf der Rückseite ist rot, der Link zum Zitieren ist grün.

\documentclass{article}
\usepackage[colorlinks,pagebackref]{hyperref}
\begin{document}
Donald E. Knuth is the inventor of \TeX~\cite{knuth}.
\begin{thebibliography}{9}
\bibitem{knuth}
Donald E. Knuth: \textit{The \TeX book}; Addison Wesley, 1984.

\end{thebibliography}
\end{document}

Ergebnis

LaTeX benötigt jedoch keine Leerzeile, die Leerzeile sieht überflüssig aus und das Beispiel funktioniert auch ohne hyperrefund die Leerzeile:

\documentclass{article}
\begin{document}
Donald E. Knuth is the inventor of \TeX~\cite{knuth}.
\begin{thebibliography}{9}
\bibitem{knuth}
Donald E. Knuth: \textit{The \TeX book}; Addison Wesley, 1984.
\end{thebibliography}
\end{document}

Ergebnis ohne Hyperref

Aber die Links und die Rückverweise sind weg, daher fügen wir sie erneut ein:

\documentclass{article}
\usepackage[colorlinks,pagebackref]{hyperref}
\begin{document}
Donald E. Knuth is the inventor of \TeX~\cite{knuth}.
\begin{thebibliography}{9}
\bibitem{knuth}
Donald E. Knuth: \textit{The \TeX book}; Addison Wesley, 1984.
\end{thebibliography}
\end{document}

Aber jetzt ist das Beispiel gebrochen und wird nicht mehr kompiliert :

Runaway argument?
 Donald E. Knuth: \textit {The \TeX book}; Addison Wesley, 1984. \end \ETC.
! File ended while scanning use of \BR@@bibitem.
<inserted text> 
                \par 
<*> knuth

?

Was ist passiert? Package hyperref(oder genauer Package backref, das von geladen wird hyperref) möchte am Ende des Bibliographieeintrags die Rückverweisliste hinzufügen. Die Syntax in LaTeX sieht jedoch nur den Beginn der Eingabe vor \bibitem, das Ende kann überall sein. In diesem Notfallpaket backrefwurde eine Einschränkung hinzugefügt, \bibitemdie den Eintrag mit einer Leerzeile beenden muss. Dann kann das Paket neu definiert werden \bibitem, um die Rückverweise am Ende des Eintrags zu setzen.

Da die leere Zeile fehlt, sucht TeX weiterhin danach, findet jedoch stattdessen das Dateiende und gibt die Fehlermeldung aus.

Heiko Oberdiek
quelle
12

C (halbverschleiert)

Dieses kleine Programm nimmt eine Zahl in die Kommandozeile und berechnet deren Fakultät. Es enthält jedoch auch hochmoderne AI-Funktionen zur Laufzeitüberprüfung, die sicherstellen, dass die Kodierungsstandards des Unternehmens, einschließlich der korrekten Verwendung von Leerzeichen und Leerzeilen, eingehalten werden. Das Entfernen einer leeren Zeile löst aus, dass der Algorithmus das nicht ausreichend wartbare Programm ablehnt.

Keine Linienfortsetzungen oder Trigraphen. Ich glaube es ist ANSI C99 gültig.

Denken Sie aufgrund der fortgeschrittenen Mathematik daran, diese gcczu verwenden , wenn Sie mit kompilieren -lm.

#include <setjmp.h>
#include <stdio.h>
#define max(x,y) ((x<y?y:x))
#define swap(x,y) ((x^=y,y^=x,x^=y))
#include <stdlib.h>
#include <math.h>
#define vfry(x,p,z,y,i) (!!y&((z##z##L##I##p##x##z##z)))
#define NDEBUG

/* 
 * Proper use of whitespace is essential!
 * Please do not remove any blank lines.
 */

const double E = 2.71828182845904523536;

int vrfy(double epsilon, int magic, const char *key, long int L) {
  /* You are not expected to understand this */
  double x=284.2891,u=2.34e56;
  while (rand()+magic*pow(epsilon,sin(x-E))!=log(u*L))
    x*=vrfy(1.0/epsilon,(int)u,&key[swap(L,magic)],L++);
  return u/lgamma(x);
}

int main(int argc, char *argv[]) {
  int N_=831293812; /* do not change, see Knuth 1987 */
  if (!vfry(E, N,_, "M=&;VT=I!9", 0xfe86ddcaL)) {
    fprintf(stderr, "Code standards violation detected!\n");
    abort();
  }
  if (argc < 2) {
    fprintf(stderr, "Usage: %s n\nComputes n!\n", argv[0]);
    exit(1);
  }
  int m=1, n=atoi(argv[1]), i;
  for (i=1; i <= n; i++)
    m *= i;
  printf("%d! = %d\n", n, m);
  return 0;
}

Spoiler

Die komplizierte vrfyFunktion wird nie aufgerufen, sondern das komisch aussehende vfryMakro. Die Verwendung der Zeichenfolgenverkettungsfunktion des Präprozessors verschleiert die Tatsache, dass wir wirklich nur die Parität von überprüfen __LINE__.

Nate Eldredge
quelle
Funktioniert auch mittcc -run
Vi.
Das ist wirklich ordentlich. Das vfrywird in der Funktionsdefinition nicht erweitert, hat mich wirklich überrumpelt.
FUZxxl,
11

C

Dieses Programm funktioniert wie erwartet (wie in den Kommentaren beschrieben), es sei denn, die vorstehende Leerzeile foo = 5;wird entfernt.

Leider bin ich einmal auf einen ähnlichen Fehler im Produktionscode gestoßen.

#include <stdio.h>

int main()
{
    int foo = 0;

    #define FROB(x) do {                                            \
        x++;                                                        \
        printf("%d\n", x);                                          \
    } while (0);                                                    \

    foo = 5;
    FROB(foo); /* prints 6 */
    FROB(foo); /* prints 7 */
    FROB(foo); /* prints 8 */

    return 0;
}

In diesem Beispiel wird das do { ... } while (0)Idiom zum Erstellen einer mehrzeiligen Anweisung in einem Makro verwendet (siehe https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for ). Das Backslash-Zeichen wird auch verwendet, um ein Zeichen #defineüber mehrere Zeilen zu verteilen . Es macht jedoch auch zwei Dinge falsch:

  • Es gibt ein Semikolon danach while (0), während die Redewendung dies normalerweise weglässt
  • Nach der letzten Zeile der steht ein Backslash #define

Wenn Sie an dieser Stelle die leere Zeile vor entfernen, foo = 5;wird diese Zuweisung nach dem printf, aber auch nach jedem Aufruf des FROBMakros ausgeführt. Infolgedessen lautet die Ausgabe nach dem Entfernen der Leerzeile wie folgt:

1
6
6
Greg Hewgill
quelle
1
Grundsätzlich ein Duplikat von codegolf.stackexchange.com/a/31662/20356
siehe auch
@TheRare Aber es ist weniger offensichtlich.
Ypnypn
6
Es ist nur weniger offensichtlich, wenn Sie nicht auf die Backslashes schauen, die sehr auffällig nach rechts schweben. (Aber da sie dort sehr auffällig nach rechts schweben, werden sie angeschaut.)
doppelgreener
3
Alle außer einem sind jedoch gerechtfertigt
QuadmasterXLII
6
@QuadmasterXLII, technisch gesehen, sind sie alle gerechtfertigt - und zwar zu Recht.
Mark
9

C / C ++

int main(){

    return __LINE__ - 3;
}

Gibt Erfolg zurück und kann als Implementierung für true verwendet werden . Wenn die leere Zeile entfernt wird, können Sie sie stattdessen als Implementierung für false verwenden.

nwp
quelle
8

Power Shell

Diese Funktion fügt zwei Zahlen hinzu.

function add ($a, $b) {
    $numbers = @($a `

            $b)
        $numbers| measure -sum| select -expand sum
}

Wenn Sie die leere Zeile entfernen, schlägt die Funktion fehl mit: Unexpected token '$b' in expression or statement.

Erläuterung

Array-Elemente können durch Zeilenumbrüche und / oder Kommas getrennt werden. Das Platzieren des Zeilenfortsetzungszeichens ( `) nach $aerfordert eine zusätzliche Zeile zum Trennen von $aund $b. Andernfalls sieht der Interpreter den Code als $numbers = @($a $b)(kein Elementtrennzeichen) an.

Rynant
quelle
7

TeX

\noindent\everypar{$\bullet$ hello }

world
\bye

Ohne die leere Zeile wird "Hallo" nicht gedruckt.

Erläuterung

TeX behandelt die leere Zeile als Absatzumbruch und \everyparwird am Anfang eines neuen Absatzes ausgeführt.

Stephan Lehmke
quelle
6

Java

import java.util.Scanner;

public class BlankLine
{
    public static void main( String[] args )
    {
        //This calculates 2^ given number
        //if you remove blank line after the next line it will always print 1
        int x = new Throwable().getStackTrace()[0].getLineNumber();

        int y = new Throwable().getStackTrace()[0].getLineNumber() - x;
        System.out.println("Number:");
        Scanner scanner = new Scanner(System.in);
        int r = 1;
        int n = scanner.nextInt();

        for(int i = 0; i < n; i++){
            r *= y;
        }
        System.out.println("2^number: "+r);
    }
}

x ist die aktuelle Zeilennummer, y ist die aktuelle Zeilennummer - x. Wenn sich zwischen ihnen eine leere Zeile befindet, ist das Ergebnis 2. Der Code berechnet also 2 ^ number.

barteks2x
quelle
1
+1 einfach, weil es Java ist, obwohl ich mich als häufiger Besucher von Code Review frage, warum Sie es nicht verwenden Math.pow?
Simon Forsberg
Weil mein Code etwas zu tun hat. Das Hinzufügen von 2 Zahlen ist etwas zu einfach.
Barteks2x
Mit Math.powund drucken Sie das Ergebnis ist auch etwas zu tun , ist es nicht?
Simon Forsberg
Und jetzt wurde mir klar, dass ich .Math.pow wirklich nutzen könnte. Ich weiß nicht, warum ich dachte, ich muss es so machen ... Vielleicht wollte ich es auf eine "hinterhältige" Weise machen.
Barteks2x
7
Sie haben zu viel Golf gespielt. Sie sollten stattdessen Code Review besuchen, wo wir alles richtig machen!
Simon Forsberg
6

Perl 5

print(<<""
Hello, World!

);

Dieser Code wird gedruckt Hello, World!. Das Entfernen der leeren Zeile führt stattdessen zu einem Syntaxfehler.

Erläuterung:

Perls Here-Doc-Syntax für mehrzeilige Zeichenfolgen lässt eine leere Abschlusszeichenfolge zu. Es ist sogar explizit dokumentiert. Durch das Entfernen der Leerzeile wird die schließende Klammer (und alles andere bis zur nächsten Leerzeile, falls vorhanden) als Teil der Zeichenfolge interpretiert, was zu einem Syntaxfehler führt.

Die Fehlermeldungen, die Sie erhalten, sind für eine solche merkwürdige Syntax-Funktion eigentlich ziemlich anständig. Wenn das Programm nach der print(<<""Zeile keine Leerzeilen enthält , sagt Perl einfach:

Kann "" vor EOF in der foo.pl - Zeile 1 nirgends ein Zeichenketten - Abschlusszeichen finden.

Wenn es ist am Ende des Programms eine leere Zeile, Sie so etwas wie diese stattdessen erhalten:

Syntaxfehler in foo.pl Zeile 4, bei EOF
  (Könnte eine außer Kontrolle geratene mehrzeilige << Zeichenfolge sein, die in Zeile 1 beginnt.)
Die Ausführung von foo.pl wurde aufgrund von Kompilierungsfehlern abgebrochen.

Ilmari Karonen
quelle
5

Stapel

@echo off
setLocal enableDelayedExpansion
set NL=^


echo Hello!NL!World

Dieser Code wird Helloin der nächsten Zeile ausgegeben World. Wenn eine oder beide Leerzeilen entfernt werden, wird überhaupt nichts ausgegeben.

Hier gibt es eine Erklärung .

unclemeat
quelle
4

Rubin

Das Löschen der ersten Zeile verursacht einen Fehler:

line = IO.readlines($0).first.chomp if line.empty? puts 34+4 else raise "Please add a newline at the beginning of the program." end
Mhmd
quelle
2
Ich liebe die Fehlermeldung. Möchte die Reaktion von jemandem sehen, der versucht, das Programm auszuführen und diese Antwort erhält.
Tomsmeding
4

Python

Ich weiß nicht, ob dies unter die Standardlücken fällt. Ich habe mir die Liste angesehen und das nicht gesehen.

src = open(__file__, 'r')
code = src.readlines()
src.close()

if code[3] == '\n':
    print 'Hello World!'

Laufen diese regelmäßig zurück

Hello World!

Führe es ohne die leere Zeile in Zeile 4 aus, also wie folgt:

src = open(
__file__, 'r')
code = src.readlines()
src.close()
if code[3] == '\n':
    print 'Hello World!'

gibt nichts zurück.

Zaxvo
quelle
3

Python 2.x

Dieses Programm gibt das fünfte Zeichen der eingegebenen Zeichenfolge aus.

import inspect

text = raw_input()
print 'Fifth character of the string:', text[inspect.getlineno(inspect.currentframe())]

Dies ist in keiner Weise verborgen. Wenn Sie die leere Zeile entfernen, erhalten Sie das vierte Zeichen und das sechste, wenn Sie eines hinzufügen.

seequ
quelle
3

Tcl

Eine Funktion, die zwei Zahlen hinzufügt (und prüft, ob die neue Zeile gelöscht wurde):

proc add {a b} {
    if {[llength [split [info body add] \n]] < 5} {error "function has been modified"}

    return [expr $a+$b]
}

Hier gibt es nichts zu verbergen, es macht, was es sagt, also verderbe ich die Erklärung nicht. Die Funktion infoist ein Schweizer Taschenmesser der Selbstbeobachtung (was andere Sprachen Reflexion nennen). info bodyGibt den Quellcode einer Funktion zurück (falls nicht in C oder Assembly geschrieben).

Ich muss zugeben, dass dies mich ratlos machte, bis ich die Javascript-Lösung sah.

Slebetman
quelle
3

C

#include <stdio.h>


int main() {
    const char* a = "You love blank lines.";
    #define print_out(a) \

    printf("%s\n", a);
    a = "You don't seem to love blank lines";
    print_out(a);
    return 0;
}

Mit der leeren Zeile aist die lokale Variable a und ohne sie der Makroparameter ...

urzeit
quelle
3

Technisch gesehen kein "Code" -Problem, sondern ein Server-Problem. Wenn dies von einem CGI-Skript an Apache gesendet wird (das in einer beliebigen Sprache generiert werden kann), sendet es eine HTTP-Antwort an den Client:

HTTP/1.x 200 OK 
Content-Type: text/html; charset=UTF-8

Hello world!

Auf der anderen Seite schlägt dies fehl, da das Leerzeichen nach dem Header fehlt.

HTTP/1.x 200 OK 
Content-Type: text/html; charset=UTF-8
Hello world!
cwallenpoole
quelle
2

JavaScript

Die Funktion whereamiantwortet mit der Position der aufrufenden Leitung relativ zu ihrer eigenen Position im Quellcode.

console.log (whereami ()) //3 line(s)  before me 


function whereami () {
    var a=function a(e){try{to}catch(c){for(var d=c.stack.split("\n"),b=0;b<d.length&&!~d[b].indexOf("a");b++);return c.stack.split("\n")[b+~~e].match(/:(\d+)/)[1]-~~window.hasOwnProperty("__commandLineAPI")}},a1=a(1),i


    i= a(2)>a(1)+4?a(1):a(1)>a1+2?a1-1:a/a1



    return ((i=(a(2)<i?i-1:a(1)>i+3?a(2)-a(1)-1:a/1)) + " line(s) "   ) + (i<a(2)?" after":(i>=a(2)?" before":"confusing")) + " me";
}


console.log (whereami ()) //3 line(s)  after me

Wenn eine leere Zeile in der whereamiFunktion entfernt wird. Die Ausgabe ist NaN line(s) confusing me. (Das Hinzufügen von Zeilen unterbricht es nicht.)

Tatsächlich wird nur die Anzahl der Zeilen zwischen ider ersten und der letzten Zeile gezählt. Wenn sie unter einen bestimmten Wert fallen. Die Referenzlinie wird gesetzt, auf NaNdie weder erfüllt NaN<callingLinenoch NaN>=callingLine. Ich habe versucht, es ein wenig in unlesbaren ternären Ausdrücken zu verstecken.

C5H8NNaO4
quelle
1
Cool. Ich hatte nicht daran gedacht, den Ausnahmestapel so zu verwenden.
nderscore
2

Perl

#!/usr/bin/perl

use strict;
use warnings;

open IN, "<".$0 or die "Did not find input files!";
while (<IN>) {
        m/blabla/ && ((<IN> =~ /\}/ && print "tra-la-la...\n") || print "ti-ri-li\n");

}
close IN;

Dieses Perl-Skript liest die Skriptdatei und prüft, ob hinter der Zeile mit "blabla" eine schließende Klammer steht.

urzeit
quelle
2

Escript

Aufgrund eines Fehlers in der escriptImplementierung muss ein gültiges Escript mindestens drei Zeilen lang sein und die erste Zeile muss eine einfache oder eine leere Zeile sein. Das folgende Skript muss also zwei leere Zeilen haben, wobei die erste die erste sein muss:

main(_) -> io:format("Hello world!~n", []), halt().

Oder es muss in zwei Zeilen unterbrochen werden, muss aber immer noch die erste leere Zeile enthalten.

main(_) ->
    io:format("Hello world!~n", []), halt().

Sonst wirst du bekommen

escript: Premature end of file reached
Hynek-Pichi-Vychodil
quelle
2

Rubin

print %q
2+2=

p(2+2)

Druckt 2+2=4, gibt aber einen Syntaxfehler ohne die leere dritte Zeile aus. %qErmöglicht, dass jedes Nicht-Wort-Zeichen als Zeichenkettenbegrenzer dient, auch das Zeilenumbruchszeichen. Die ersten drei Codezeilen entsprechen also tatsächlich print %q"2+2="oder nur print "2+2=". Da der Zeilenumbruch danach 2+2=als Anführungszeichen verwendet wird, wird er nicht auch als Zeilenumbruch analysiert , sodass Sie unmittelbar danach einen neuen benötigen.

Histokrat
quelle
1

Schlaflosigkeit (beide Versionen)!

Þyoo

â

Dieser Code gibt ein ~ aus (fragen Sie nicht warum, Schlaflosigkeit ist seltsam). Wenn Sie die leere Zeile entfernen, wird stattdessen ein ÿ gedruckt.

Übrigens ist dieser erste Buchstabe ein Dorn .

Pfeffer
quelle
1
Hurra, Dornen! Habe diesen Charakter seit Ewigkeiten nicht gesehen, +1.
Addison Crump
0

C ++

Dies ist ein klassischer und ziemlich dummer Trick. Sie werden wissen, was es ist, wenn Sie es sehen. Dies ist nur zur Vervollständigung hier. Als solche markiere ich dies als eine Community-Wiki-Antwort.

int main() {
    //This program won't work without the next line, why??/

    return 1;
}

Warum funktioniert das?

CrazyM4n
quelle
13
Dies ist tatsächlich eine der Lücken.
Mhmd
@ Mhm war mir nicht bewusst. So oder so, ich weiß, dass die Leute das immer bei solchen Fragen verwenden, und ich wollte das hier einfach so lassen, damit es jemand nicht schlau findet, das zu tun.
Aearnus
1
Diese Antwort ist aus zwei Gründen falsch. Der erste ist , dass ??/Mittel \​, also ??//Mittel \/, und wenn die Linie in endet nicht \​, gibt es keine Zeilenfortsetzungs. Das zweite ist, dass das Verhalten genau das gleiche ist, unabhängig davon, ob return 0;es ausgeführt wird, da dies das Standardverhalten ist, wenn die Ausführung von maindas Schließen erreicht }.
HDV
@hvd Da. Ich habe es repariert.
Aearnus
3
@cra I know people always use this in these kinds of questiondeshalb haben wir es zu einem Standard-Schlupfloch gemacht
undergroundmonorail
0

Fügen Sie dies in eine HTML-Datei ein und öffnen Sie sie in Ihrem Browser. Es ist ziemlich einfach, aber etwas knifflig, da es die Anzahl der Leerzeilen im Dokument benötigt und ein Array indiziert, um eine Funktion aufzurufen, die eine Warnung anzeigt.

<body>
<script>
[null, function(){alert("GIVE ME MY LINE BACK")}, function(){alert("2 + 2 = " + (2+2))}][document.body.innerHTML.split("\n\n").length]()

</script>
</body>

Dies ist ein Verstoß gegen die Grenzregeln. Technisch gesehen hat JavaScript keine mehrzeiligen Zeichenfolgen. Dies ist der einzige Grund, warum dies funktioniert.

Da in einem Skript-Tag ein Syntaxfehler auftreten kann, ohne die anderen Skript-Tags zu beeinträchtigen, wird nur dann ein positives Ergebnis angezeigt, wenn auf der Seite ein Fehler vorliegt. Der Fehler verhindert, dass die zweite Warnung ausgelöst wird, da sie sich im selben Skript-Tag befindet.

<body>
<script>
window.onerror=function(){
  alert("2 + 2 = " + (2+2));
}
</script>
<script>
var a = "\

";
alert("GIVE ME MY LINE BACK!");
</script>
</body>
Räuber
quelle
0

Rubin

puts (% #{ARGV[0].to_i + ARGV[1].to_i}

)

Das Geheimnis ist, dass die neue Zeile wirklich ein Tabulator ist, dann eine neue Zeile. Ich weiß nicht, ob das zählt, aber ich dachte, es wäre ein Hackmesser. Das Zeichen nach dem %ist ebenfalls ein Tabulator, aber aus irgendeinem Grund wird es nicht wie ein Tabulator angezeigt. Ich verwende Rubys Prozentnotation, um einen String zu erstellen, der die ersten beiden Argumente hinzufügt, die an das Skript übergeben werden. Mehr dazu hier: http://teohm.com/blog/2012/10/15/start-using-ruby-percent-notation/

addison
quelle
Es zählt eigentlich nicht, lesen Sie die Anweisungen: "No Whitespace Trottel." Genau eines \nsollte anwesend sein und entscheidend dafür sein, dass das Programm wie erwartet funktioniert.
Naftuli Kay
Ah ok :( Nun, ich habe es versucht
Addison
1
Ich denke, Sie können dies jedoch beheben: Ein Zeilenumbruch kann selbst ein Prozentbegrenzer sein.
Histokrat