Напишите фрагмент кода для вывода номера строки самого оператора 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.