Напишіть фрагмент коду, щоб вивести номер рядка самого твердження про друк / вихід (у формі "Hello World, з рядка X!")


25

Змагання

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

Правила

  • У цьому контексті ми хочемо, щоб номер першого рядка заяви, який видає рядок, відображавсяstdout
  • Вам слід уникати простого пошуку вихідного коду у вигляді рядка (або файлу, або квита), щоб знайти номер рядка
  • Якщо будь-які додаткові пробіли або заяви (які не переривають потік коду) додані до вихідного коду, вони повинні бути відображені під час виконання (після компіляції, якщо це застосовується)

Рекомендації

Якщо це передбачено мовою, ви можете використовувати винятки / сліди стека для досягнення цієї мети. Постарайтеся використовувати код, який переноситься для різних систем / реалізацій, але зауважте, що це не є обов'язковою умовою. Використання визначених змінних на зразок __LINE__, хоча це допускається правилами, не рекомендується.

Переможець

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

  • Голосуючи, будь ласка, врахуйте творчість чиєїсь відповіді, наскільки вона складна чи цікава . і труднощі / обмеження використовуваної мови програмування


Що ви маєте на увазі під "номером першого рядка"? Ви говорите про те, що має статися, якщо вислів охоплює кілька рядків?
user2357112 підтримує Моніку

@ user2357112 так, просто для вирішення будь-якої неоднозначності, якщо комусь потрібно було використовувати заяву milti-line.
Прорив

Заголовок дуже чіткий, але, можливо, трохи довгий.
примо

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

1
@Markasoftware, якщо до нього було додано рядок, вихід не зміниться, щоб відобразити це.
примо

Відповіді:


48

Sinclair Basic

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
Це чудова відповідь, тому що це має дурну, але специфічну перевагу в аспекті мови BASIC, який часто не зустрічається в інших мовах (особливо сучасних). Це може бути не найпопулярнішим (час покаже), але я навряд чи бачу, як це менш цікаво, ніж використовувати константу, наприклад __LINE__ або отримати інформацію про налагодження з поточного кадру стека (як це робить більшість інших відповідей на даний момент).
Нік

2
Розумний, але я був би розчарований, якби більше нічого не закінчилось, ніж цей.
agweber

35

Java

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 () викликає (новий виняток ()). GetStackTrace (), якщо його викликають у поточній темі, тож те саме
DHall

1
дивно .... 2х однакова відповідь та 2 різні суми оновлених платежів ... (може використовуватися як джерело RNG ...) (те саме тут: 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
Так, це, безумовно, цікавіше :)
Тал

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
Мені знадобилося ... довгий час, щоб побачити, як це працює. Стільки червоних оселедців! Це смачно.
sehe

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

це все ще паршиве і занадто очевидне рішення ІМО. Мені цікаво, чому люди розміщували всілякі варіанти цього рішення на всіх мовах світу (включаючи 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) + ' !')

Примітка: Вирази, оцінені в межах хромованої консолі розробника, будуть загорнуті у withвиписку. Таким чином, нам потрібно декрементувати рядок, якщо це так


2
дат стек , хе-хе. Перевірено, що працює над Firefox.
Прорив

1
@Breakthrough :) Так, він працює між браузером (протестується лише з останніми Chrome, FF, IE). Chrome потребує особливої ​​обробки, коли він оцінюється з консолі, оскільки він записує кожне твердження в withпункт.
C5H8NNaO4

2
Цікаве, але неоднозначне ім’я користувача. Мононатрієвий глутамат, можливо? (До речі, я думаю про те, щоб запитати про ДНК та амінокислоти, з яких одна глутамінова кислота.)
рівень річки Св.

@steveverrill According to google, you are correct!
kitcar2000

@kitcar2000 Probably. But there are other lesser-known compounds with this formula: Sodium methylaspartate or nitropentanoate, for example.
Level River 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

Hello world, from line 8!

This self-reading code contains a self-referencing hash. The SHA256 sum of the last line (with the beginning whitespace and without trailing whitespace) begins with cc46f7.... When it hashes the print line, it finds that the hash matches the magic value it's searching for.


couldn't you just set line_num = to -1 and have the print outside the loop and get ride of the magic hash?
dave

1
@dave not sure I follow you. The magic hash is what makes this solution clever.
Tim S.

+1 for literal interpretation of my rules :) Very clever.
Breakthrough

5
@Stefan This site is all about worst practices, though. ;)
Tim S.

1
@sehe Most likely, this was due to whitespace issues. I didn't have a newline at the end of the file when I made it. I've added a line to strip whitespace from the end of the line before hashing. It should work more consistently now. (also make sure you're not converting the spaces to tabs) I tried uploading it to ideone to show you a live version, but it can't read its own file there.
Tim S.

9

GNU COBOL

Well, they said it couldn't be done. Actually, it was I who said it couldn't be done. Now it's done, and an obsolete language feature re-implemented using the method applied.

The question states:

Якщо будь-які додаткові пробіли або заяви (які не переривають потік коду) додані до вихідного коду, вони повинні бути відображені під час виконання (після компіляції, якщо це застосовується).

Будь-яка кількість матеріалу може бути вставлено до трьох 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 отримати номер вихідного рядка в запущеній програмі з запущеної програми - це a 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

Java

Використовуючи поведінку трасування стека Exception, щоб отримати поточний рядок. до тих пір, поки 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

Java

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

Пітон

import inspect
print ("Hello world from line %d!" % (inspect.getlineno(inspect.currentframe())))

Вихідні дані

Hello World from line 2!

1
Найкращий Python досі!
kirbyfan64sos

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 рядка


No idea what this was, but I believe your output claim, so +1 ;-)
ysap

1
For those who question the power of mighty Befunge, try it out here: quirkster.com/iano/js/befunge.html
Justin

6

C

By using a variadic macro, we can make a print function which automatically adds the line number to the end of an arbitrary printf statement, and always prints to stdout.

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;
}

outputs:

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

Note: I deviated from the pattern to demonstrate that printfl is still a valid variadic function; if you really care about the format of the output, you can always change the literals I use.


This only works if you use a constant format string. It fails if you pass in any other expression for the format string.
Snowbody

5

Bash

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

Output

Hello World, from line 4!

@professorfish ... what's wrong with MY style to show MY answer? You should at least explain why you manipulate my artwork... :-P

2
did I change the code? if I did, I'm sorry. I was just worried that non-bash users wouldn't be able to tell what was the source code and what was the output

1
And evryone else besides me loves seeing his stuff being changed without commenting why? Strange place...

3
It was basically a formatting fix. There's nothing really wrong with those AFAIK

Using defined variables like LINE, although allowed by the rules, are discouraged.
vaxquis

5

D

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

Using defined variables like LINE, although allowed by the rules, are discouraged.
vaxquis

5

C or C++, and AWK

lineno.c:

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

Usage:

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

Output:

Hello, World, from line 3

Notes:

  • No user written code searches the file.
  • g++ will work on a c++ file.

4

Kind of boring in Ruby:

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

This isn't cheating, right?


Nope, this isn't cheating! This challenge will obviously be a lot easier in some languages and more difficult in others, however, which was why I posted it :) (I see now why the inclusion of a scoring criteria is so important)
Breakthrough

Using defined variables like LINE, although allowed by the rules, are discouraged.
vaxquis

1
@vaxquis Yeah, that statement was added after this answer.
Ajedi32

4

Javascript

One line using stack trace.

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

3

Cobra

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

3

Ruby

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

Cheap Move

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!"

And:

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

Both work like this:

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

+1, but Write-Host doesn't write to stdout. Simply passing the string will send it to stdout. E.g. "Hello World, from line {0}!" -f (gcs| %{$_.ScriptLineNumber})[0]
Rynant

@Rynant Good point! I'll update my answers to consider that...
DarkAjax

3

Python

import traceback

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

Short and sweet.


3

Perl

Another Perl one:

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.