Напишите фрагмент кода для вывода номера строки самого оператора print / output (в форме «Hello World, из строки X!»)


25

Соревнование

Напишите программу, которая выводит Hello World, from line X!, где Xномер строки в исходном коде, самого фактического оператора печати.

Правила

  • В этом контексте мы хотим, чтобы номер первой строки оператора, который выводит строку , отображался вstdout
  • Вы должны избегать простого поиска по вашему исходному коду в виде строки (файла или quine), чтобы найти номер строки
  • Если какие-либо дополнительные пробелы или операторы (которые не прерывают поток кода) добавляются в исходный код, это должно быть отражено во время выполнения (после компиляции, если применимо)

рекомендации

Если это предусмотрено языком, вы можете использовать исключения / трассировки стека для достижения этой цели. Старайтесь изо всех сил использовать код, переносимый между различными системами / реализациями, но учтите, что это не является обязательным требованием. Использование определенных переменных, таких как __LINE__, хотя и разрешено правилами, не рекомендуется.

Победитель

  • Это конкурс популярности (завершился 10 июня 2014 г.), в котором ответ, набранный сообществом за наибольшее количество голосов, будет объявлен победителем на основе текущих голосов на момент голосования.

  • При голосовании учитывайте креативность чьего-либо ответа, насколько он сложен или интересен . и трудности / ограничения используемого языка программирования


Что вы подразумеваете под "номером первой строки"? Вы говорите о том, что должно произойти, если утверждение занимает несколько строк?
user2357112 поддерживает Monica

@ user2357112 да, просто чтобы разрешить любую двусмысленность, если кому-то нужно использовать оператор в несколько строк.
Прорыв

Название очень четкое, но, возможно, немного длинное.
Примо

1
Все ответы на это скучны, потому что это такой плохой вопрос. Это похоже на то, что спрашивающий не знал о существовании LINE . На самом деле я подписался специально для того, чтобы проголосовать, я подумал, что это так плохо.
Дэйв

1
@Markasoftware, если перед ним была добавлена ​​строка, вывод не изменился бы, чтобы отразить это.
Примо

Ответы:


48

Синклер Базовый

10 PRINT "Hello world, from line ";PEEK 23621;"!"

Привет, мир, из строки 10!

Это будет работать для любой строки по PEEKадресу, в котором хранится номер текущей строки, поэтому также будет работать следующее:

341 PRINT "Hello world, from line ";PEEK 23621;"!"

Привет, мир, из строки 341!


И, к тому же, Timex / Sinclair BASIC!
Гейб

Я не притворяюсь, что знаю этот язык, но разве вы не можете пропустить, STR$если вы замените +знаки точкой с запятой?
Мистер Листер

@MrLister Да, это определенно сработает, но я всегда использую +s по привычке.
kitcar2000

40

Бейсик

Я думаю, что это делает все, что просили:

10 PRINT "Hello World, from line 10!"

5
If any additional whitespace or statements (which do not interrupt the flow of the code) is added to the source code, it should be reflected at run-time (after compiling if applicable), Намерение здесь. Кроме того, это первая строка источника, а не 10-я.
Билл Вуджер,

30
Это может быть первая строка в исходном коде, но это все еще строка 10 .
брезгливый оссифраж

13
Я считаю, что это твердо подпадает под категорию больше не смешно . Это действительно невообразимо и неинтересно, хотя буквально оно соответствует требованию. Почему так много голосов? (Я понизил)
Тим С.

18
Это отличный ответ, потому что он использует глупое, но особенное преимущество аспекта языка Бейсик, который обычно не встречается в других языках (особенно современных). Возможно, он не самый популярный (время покажет), но я не могу понять, насколько он менее интересен, чем использование константы, такой как __LINE__, или получение отладочной информации из текущего фрейма стека (как большинство других ответов в настоящее время делают).
Ник

2
Умно, но я был бы разочарован, если бы ничто иное не получило больше голосов, чем этот.
agweber

35

Джава

public class Hello{
    public static void main(String[] args) {
        System.out.println("Hello World, from line "+new Exception().getStackTrace()[0].getLineNumber()+"!");
    }
}

1
Я бы предпочелThread.currentThread().getStackTrace()
Cruncher

3
Thread.getStackTrace () вызывает (new Exception ()). GetStackTrace (), если вызывается в текущем потоке, поэтому это то же самое
DHall

1
странно .... 2 раза один и тот же ответ и 2 разные суммы возражений ... (можно использовать в качестве источника ГСЧ ...) (то же самое здесь: codegolf.stackexchange.com/a/30058/10801 )
masterX244

@ masterX244 эти два ответа не совсем идентичны; в этом getLineNumber()методе используется метод трассировки стека, а в ответе, на который вы ссылаетесь, используется toString()номер строки.
Прорыв

9
@ masterX244 также стоит отметить, что этот ответ появился на 2 часа раньше. Второй раз, когда я вижу ответ, он не такой интересный, как первый.
Примо

30

Perl

close STDERR;
open FOOBAR,">",\$_;


print!warn,'Hello World, from line ',/(\d+)\.$/,'!';

Не такой короткий, как использование __LINE__, но, возможно, более интересный.

warnявляется средством отладки, которое выдает инструкцию STDERR, указывающую, в каком файле и на какой строке было выдано предупреждение ... если только оно STDERR не было ранее закрыто или недоступно иным образом, в этом случае предупреждение выдается для самого последнего открытого файла обрабатывать - это недокументированное поведение. Я не уверен, будет ли это лучше классифицировано как функция или ошибка.

Здесь STDERRзакрывается, и новый дескриптор файла, идентифицируемый как FOOBARоткрытый, направляется в переменную $_. Затем он анализируется для получения номера строки предупреждения, встроенного в оператор печати.


3
Да, это определенно интереснее :)
Tal

27

C ++

#include <iostream>
#include <utility>
#include <type_traits>

#define __(A,B,C,...) B##C##A
#define _(A,...) __(__VA_ARGS__, A)
template<unsigned...Is> struct v;
template<unsigned I0, unsigned... Is> struct v<I0, Is...>:v<I0-1,I0-1, Is...> {};
template<unsigned...Is> struct v<0,Is...>:std::integral_constant<unsigned, sizeof...(Is)> {};

int main() {
  std::cout << "Hello world from line " << v<_(EXTRACT,_(Q,_,E,_,$$main$$,),_(@22,,_,_),_(Z,N,L,I,_,,L),__STACK_TRACE__)>::value << "\n";
}

живой пример


2
Это ... волшебство
Паладин

1
Мне потребовалось ... много времени, чтобы увидеть, как это работает. Так много красных сельдей! Это вкусно.
Се

1
Итак, как это работает?
0x499602D2


16

C #

C # 5.0 [CallerLineNumber]делает свое дело:

using System;
using System.Linq;
using System.Runtime.CompilerServices;
namespace LineNumberConsole
{
    class Program
    {
        public static void Main()
        {
            Console.WriteLine("Hello World, from line {0}!", ToRoman(GetLineNumber()));
            Console.ReadLine();
        }

        private static int GetLineNumber([CallerLineNumber] int sourceLineNumber = 0)
        {
            return sourceLineNumber;
        }

        private static string ToRoman(int number)
        {
            // TODO: Copy some source code from http://pastebin.com/w0hm9n5W
            // Skipped here for brevity
            return number.ToString();
        }
    }
}

Выход

Hello World, from line X!

Есть ли какая-то конкретная причина использовать римские цифры?
Коул Джонсон

4
Когда строка печати - строка 10, вопрос интерпретируется буквально. Xв римских цифрах есть 10.
Οurous

Римские цифры - приятное прикосновение!
NPSF3000

15

С

#include <stdio.h>
main(){
printf("Hello World, from line %d!", __LINE__);
}

Использование определенных переменных, таких как LINE , хотя и разрешено правилами, не рекомендуется.
vaxquis

@vaxquis, да, но мой ответ предшествует этому редактированию вопроса
gnibbler

Это все еще паршивое и слишком очевидное решение IMO. Мне интересно, почему люди публикуют всевозможные варианты этого решения на всех языках мира (включая PHP, D, Perl) вместо того, чтобы пытаться сделать что-то смешное или интригующее?
vaxquis

14

питон

Пример (10 строк, 213 символов):

import sys
import traceback
lineno = None
while True:
    try:
        print 'Hello World, from line %d!' % lineno
        break
    except:
        lineno = traceback.tb_lineno(sys.exc_info()[2])
        continue

Попробуйте онлайн здесь . Можно добавить не изменяющий поток код и пробел, и программа отобразит обновленный счетчик строк, а также этот фрагмент кода можно также использовать в любом месте существующей программы. Ожидаемый результат:

Hello World, from line 6!

Другой пример (попробуйте онлайн здесь), чтобы показать, что он работает при добавлении кода / пробелов. Ожидаемый результат:

Down we go...
Gotta catch 'em all.
Down we go...
Hello World, from line 11!
Awesome!

12

Javascript

function getLine(n) {
   try {
      to
   } catch (dat) {
      var stack = dat.stack.split('\n');
       for (var i = 0; i < stack.length; i++) {
           if (~stack[i].indexOf ('getLine')) break;          
       }
      return dat.stack.split ('\n')[i + ~~n].match (/:(\d+)/)[1] - ~~window.hasOwnProperty ('__commandLineAPI')
   }
}
//Line 12
console.log ('Hello World, from line ' + getLine(1) + ' !')

Примечание. Выражения, вычисленные в консоли разработчика Chrome, будут заключены в withоператор. Таким образом, нам нужно уменьшить строку на единицу, если это так


2
стек данных , хе-хе. Проверено работает на Firefox.
Прорыв

1
@Breakthrough :) Да, он работает в кросс-браузерном режиме (тестируется только с последними версиями Chrome, FF, IE). Chrome требует особой обработки при оценке из консоли, так как он заключает в себе каждый оператор в withпредложении.
C5H8NNaO4

2
Интересное, но неоднозначное имя пользователя. Возможно, глутамат натрия? (Кстати, я подумываю над вопросом о ДНК и аминокислотах, одной из которых является глутаминовая кислота.)
Level River St

@steveverrill Согласно Google, вы правы !
kitcar2000

@ kitcar2000 Возможно. Но есть и другие менее известные соединения с этой формулой: например, метиласпартат натрия или нитропентаноат.
Уровень Река St

11

Python 3

import hashlib
with open(__file__) as f:
    line_num = 0
    for line in f.readlines():
        line = line.rstrip() # make it work with or without newline at the end
        line_num += 1
        if hashlib.sha256(bytes(line, "UTF-8")).hexdigest()[0:6] == 'cc46f7':
            print('Hello world, from line {}!'.format(line_num)) # cc46f7

Привет, мир, из строки 8!

Этот код для самостоятельного чтения содержит хеш, ссылающийся на себя. Сумма SHA256 последней строки (с начальным пробелом и без конечного пробела) начинается с cc46f7... . Когда он хеширует printстроку, он обнаруживает, что хеш соответствует магическому значению, которое он ищет.


Вы не могли бы просто установить line_num = в -1 и получить печать вне цикла и получить волшебный хеш?
Дэйв

1
@ Дэйв не уверен, что я следую за тобой. Волшебный хэш делает это решение умным.
Тим С.

+1 за буквальное толкование моих правил :) Очень умно.
Прорыв

5
@Stefan Этот сайт все о худших методах, все же. ;)
Тим С.

1
@sehe Скорее всего, это было связано с пробелами. У меня не было новой строки в конце файла, когда я сделал это. Я добавил строку для удаления пробелов из конца строки перед хэшированием. Это должно работать более последовательно сейчас. (также убедитесь, что вы не конвертируете пробелы во вкладки) Я попытался загрузить его в ideone, чтобы показать вам живую версию, но он не может прочитать свой собственный файл там.
Тим С.

9

GNU COBOL

Ну, они сказали, что это невозможно сделать. На самом деле, это я сказал, что это невозможно сделать. Теперь все готово, и устаревшая языковая функция повторно реализована с использованием примененного метода.

Вопрос гласит:

Если какие-либо дополнительные пробелы или операторы (которые не прерывают поток кода) добавляются в исходный код, это должно быть отражено во время выполнения (после компиляции, если применимо).

Любое количество материала может быть вставлено до трех DISPLAYсекунд , которые вызывают начало вывода, и все , что после того, какDISPLAY с будет «прерывание потока кода», так что это нормально.

В языке COBOL был TRACEглагол (оператор), который просто перечислял исходные номера строк по мере их выполнения (нет доступа к номеру строки в программе). Несмотря на ограниченное использование, я включил реализацию TRACE.

   ID Division.
   Program-ID. HIWHERE.
   ENVIRONMENT DIVISION.
   configuration section.
          source-computer. TinkerToy with debugging mode.
   Procedure Division.
   Declaratives.
   Debug-Declaratives Section.
       Use For Debugging on a b
       .
   Debug-Declaratives-Paragraph.
       Display Debug-Line "!"
       .
   End Declaratives
       .
   Main-Program Section.
       DISPLAY "Perform"
       Display "Hello World, from line " no advancing Perform b
       display "GO TO"
       Display "Hello World, from line " no advancing GO TO a
       .
   a.
       dISPLay "Fall through"
       Display "Hello World, from line " no advancing. b.
   The-Last-bit-OF-the-PROGRAM.
       GOBACK
       .

Выход

Perform
Hello World, from line     18!
GO TO
Hello World, from line     20!
Fall through
Hello World, from line     23!

В качестве демонстрации силы и гибкости написания языка в этом примере используются смешанные, полностью строчные и полностью прописные буквы одновременно. Неважно, как при обработке все «складывается» в верхний регистр.

Единственный стандартный способ получения COBOL исходного номера строки в запущенной программе, из запущенной программы, - с помощью DEBUGGING DECLARATIVE. В пределах SECTION, строго в пределах параграфа SECTION, такого декларативного документа, у вас есть доступ к специальному реестру DEBUG-LINE. Он содержит номер строки источника глагола (оператора), который вызвал передачу управления определенному имени процедуры (параграф или SECTION).

Таким образом, с PERFORM, или GO TO, или «провалиться» параграф в декларациях отладкиSECTION выполняется.

Да, но DISPLAY не вызывает передачу контроля.

Нет проблем. Поместите это в ту же самую линию как передача контроля.

Проблема, поскольку, если «любые дополнительные пробелы или операторы (которые не прерывают поток кода) добавляются в исходный код, это должно быть отражено во время выполнения (после компиляции, если применимо)».

Итак, поместите его в ту же строку, но перед передачей управления, разделите содержимое элемента DISPLAYна две части (помните: «В этом контексте мы хотим, чтобы номер первой строки оператора, который выводит строку, отображался») ) и вывести первую часть до передачи управления, а вторую часть изDEBUG-LINE один раз внутри процедуры отладки.

Последний хитрый бит предназначен для «провала» («процедуры» могут быть PERFORMотредактированы, могут быть целью GO TOили могут быть введены просто следующей строкой). В этом случае поместите в DISPLAY строку, которая определяет процедуру, но перед определением .

Имена «процедур» ( aи b) были значительно сокращены, чтобы позволить им поместиться в той же исходной строке, что и DISPLAY. Строго говоря, имя процедуры на языке COBOL должно начинаться где-то с восьмого столбца до столбца 11. Однако синтаксис в наши дни гораздо более расслаблен. В той степени, в которой я могу определить имя процедуры в той же строке, что и некоторый код. Даже встроенный в код. Требуется осторожность, а иногда и полная остановка.

в PROCEDURE DIVISION каждой показанной полной остановке требуется, и не более того.

Скомпилировать:

cobc -x -g hiwhere.cbl

Выполнить (Linux):

COB_SET_DEBUG=Y ./hiwhere

Наконец, возврат TRACE (без READY / RESET).

   ID Division.
   Program-ID. tRacE.
   ENVIRONMENT DIVISION.
   configuration section.
          source-computer. TinkerToy with debugging mode.
   Procedure Division.
   Declaratives.
   Debug-Declaratives Section.
       Use For Debugging on a
       .
   Debug-Declaratives-Paragraph.
       Display Debug-Line
       .
   End Declaratives
       .
   Main-Program Section.
  *    Just append "perform a" to a single-line statement.
       DISPLAY "1" . perform a
       Display "2" . perform a
       display "3" . perform a
  *    Or prepend "perform a." for a multi-line statement, or a
  *    statement which won't "come back". 
       perform a. GOBACK
       .
   a.
       CONTINUE
       .

Выход:

1
    17
2
    18
3
    19
    20

Где 1, 2 и 3 выводятся из трех операторов DISPLAY, а 17, 18, 19 и 20 - номера строк «исполняемых» (не отладочных) строк.


8

Джава

Использование поведения трассировки стека исключений для получения текущей строки. до тех пор, пока Printstatement не искажается в несколько строк или не искажается файл класса, он должен работать

public class PrittLnbr
{
    public static void main(String[] args)
    {
        System.out.println("Hello World, from line "+new Error().getStackTrace()[0].toString().split(":")[1]+"!");
    }
}


6

Perl

print 'Hello World, from line '.__LINE__.'!';

13
Это также правильное решение PHP.
MrLore

6

Джава

public class HelloFrom {
    public static void main(String[] args) {
        System.out.println("Hello World, from line " + Thread.currentThread().getStackTrace()[1].getLineNumber() + "!");
    }
}

технически то же самое, что и я ( codegolf.stackexchange.com/a/30058/10801 )
masterX244

2
Вроде, кроме использования текущего потока вместо создания новой ошибки для получения трассировки стека. Там нет никакой ошибки;)
Cineris


6

Befunge

Сделано просто для удовольствия.

>00g1+:00p"v"\10v  
    v-*45g00p\g <  
#v+1_$10g1vv,,,,<  
^<p000p01+<#>,,,^  
>" enil morf ,oll"v
@.,,,,,,,,,<^,"He"<

Условно: верхний левый угол кода должен быть 0 <x <20 и 0 <= y <62; и две первые ячейки должны быть пустыми.

пример:

                         v                  

                         0                  
                         0                  
                         0                  
                         p                  
                         0                  
                         1                  
                         0                  
                         p                  
                         >00g1+:00p"v"\10v  
                             v-*45g00p\g <  
                         #v+1_$10g1vv,,,,<  
                         ^<p000p01+<#>,,,^  
                         >" enil morf ,oll"v
                         @.,,,,,,,,,<^,"He"<

Будет вывод:

Здравствуйте, из строки 10



1
Для тех, кто ставит под сомнение силу могущественного Befunge, попробуйте здесь: quirkster.com/iano/js/befunge.html
Джастин

6

С

Используя переменный макрос, мы можем создать функцию печати, которая автоматически добавляет номер строки в конец произвольного оператора printf и всегда печатает в стандартный вывод.

test.c:

#include <stdio.h>

#define printfl(format, ...) fprintf(stdout, format " From line %d\n", ##__VA_ARGS__, __LINE__)

int main() {
    printfl("Hello World! I have %d argument(s).", 1);
    return 0;
}

выходы:

% ./test
Hello World! I have 1 argument(s). From line 6

Примечание: я отклонился от шаблона, чтобы продемонстрировать, что printfl все еще является допустимой функцией с переменным числом аргументов; если вы действительно заботитесь о формате вывода, вы всегда можете изменить литералы, которые я использую.


Это работает только если вы используете постоянную строку формата. Сбой, если вы передадите любое другое выражение для строки формата.
Snowbody

5

удар

#
# some comments to fill some lines...
#
echo "Hello World, from line $LINENO!"

Выход

Hello World, from line 4!

@professfishfish ... что не так с моим стилем, чтобы показать мой ответ? Вы должны хотя бы объяснить, почему вы манипулируете моей работой ... :-P

2
я изменил код? если я сделал, извини. Я был просто обеспокоен тем, что пользователи, не являющиеся пользователями bash, не смогут сказать, что было в исходном коде и что было в результате

1
И всем, кроме меня, нравится видеть, как его вещи меняют, не комментируя, почему? Странное место ...

3
Это было в основном исправление форматирования. Там нет ничего плохого с этими

Использование определенных переменных, таких как LINE , хотя и разрешено правилами, не рекомендуется.
vaxquis

5

D

void main ()
{
    import std.stdio;
    writefln("Hello World, from line %d", __LINE__);
}

Использование определенных переменных, таких как LINE , хотя и разрешено правилами, не рекомендуется.
vaxquis

5

C или C ++ и AWK

lineno.c:

// code or comments
// ....
#error Hello World, from line
// other code or comments

Использование:

gcc lineno.c 2>&1 | awk '{ split($0,a,":"); ; printf("%s %s!\n", gensub(".*#error ","",1), a[2]); exit; }'

Выход:

Привет, Мир, из строки 3

Заметки:

  • Пользовательский код не ищет файл.
  • g ++ будет работать с файлом c ++.

4

Вид скучного в Ruby:

puts "Hello World, from line #{__LINE__}!"

Это не обман, верно?


Нет, это не обман! Эта задача, очевидно, будет намного проще в некоторых языках и более трудной в других, однако, именно поэтому я разместил ее :) (теперь я понимаю, почему включение критерия оценки так важно)
Прорыв

Использование определенных переменных, таких как LINE , хотя и разрешено правилами, не рекомендуется.
vaxquis

1
@vaxquis Да, это утверждение было добавлено после этого ответа.
Ajedi32

4

Javascript

Одна строка с использованием трассировки стека.

(function (o) { console.log("Hello World, from line " + (Error.captureStackTrace(o) || o.stack.match(/\d+/)[0] - !!__commandLineAPI) + "!"); })({});

3

кобра

class Program
    def main
        print 'Hello World, from line [System.Diagnostics.StackFrame(true).getFileLineNumber]!'

3

Рубин

File.write "hello.rb", "x=2\n"+"x+=1\n"*rand(rand(100))+'puts "Hello World, from line #{x}!"'
system "ruby hello.rb"
File.delete "hello.rb"

3

PowerShell

Дешевое движение

Function LemmeGetDatError() {
    "Too busy chuggin along"
    "Then all of a sudden, I meet a new programmer"
    "And he's all like"
    Write-Output "$(Try {"Hello World from"; Throw "error" } Catch {$_.ScriptStackTrace.Split(":")[1]})"
}

LemmeGetDatError

3

Powershell

$l=(Get-PSCallStack | ForEach{$_.Location})[0].split(' ')[-1]; "Hello World, from line $l!"

А также:

try{ I AM ERROR. } catch { $l=$error[0].InvocationInfo.ScriptLineNumber; "Hello World, from line $l!" }

Оба работают так:

PS C:\MyFolder> .\helloworld.ps1
Hello World, from line 1!

+1, но Write-Hostне пишет в стандартный вывод. Простая передача строки отправит ее на стандартный вывод. Например"Hello World, from line {0}!" -f (gcs| %{$_.ScriptLineNumber})[0]
Rynant

@Rynant Хорошая мысль! Я
обновлю

3

питон

import traceback

print 'Hello World, from line %i!' % traceback.extract_stack()[0][1]

Коротко и сладко.


3

Perl

Еще один Perl один:

use warnings;

$SIG{__WARN__} = sub { ($line = shift) =~ s/\D//g; };

$x=$x+1; print "Hello World, form line $line!\n";
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.